跳到主要內容

uva 10120

此證明參考至http://www.algorithmist.com/index.php/UVa_10120

M=k1+3+5+7+…+(2k-1)=k2

Frank 可以輕易地走到k2的位置,只要一直往前就可以了

而當Frank在R[x]的位置,下一次跳躍的距離就是2k+1

Proof 1.1 “如果x-(2k+1)>=1(代表往回跳不會超過邊界),Frank可以到達R[x+2](x+2<=M)”

如果Frank往回跳(2k+1)的值,再跳回來(2k+3),公式會是(x-(2k+1)+(2k+3))=(x+2)

而且x-(2k+1)>=1 && (x+2)<=N 總之就是邊界別超過

 

Proof 1.2 “如果Frank在R[x],然後下一次跳躍的距離是2k+1,只要x-((2k+1)+(y-1)*2)>=1

Frank就可以從R[x]到R[x+2y](0<=y and x+2y<=N)”

假設x-((2k+1)+(y-1)*2)>=1(0<=y && x+2y<=N)

當y=0的時候,x=x+2y  ,理所當然 我們就在x上

當y=1的時候,x - (2k+1) = x-((2k+1)+(y-1)*2) >= 1由(proof 1.1)可以得知可從x到x+2

當y>1的時候,使用歸納法,假設我們可以旅行x到x+2(y-1)=x+2y-2

而假設的限制是x-((2k+1)+(y-1)*2)>=1,如果目前在x而下一步是2k+1,就好比目前在x+2(y-1)

而下一步是2*(k+(y-1))+1,因為我們需要兩次的跳躍才會讓x到x+2。為了讓歸納法有效,

我們需要有一些限制,目前的點-下一步要走的距離>=1,在這種情況下,就好比是

(x+2(y-1)) - (2*(k+2(y-1))+1) >=1

做一些處理轉換之後

就會變成這樣x - (2k + 1 + 2(y - 1)) > = 1,跟我們一開始的假設一樣,所以這個歸納法成立

 

證明證完了 再來就是實作這題的部分,我們需要一些方法來走道R[M]

這些石頭是這樣擺設的 R[1], R[2], ... ,R[M],...

如果M是奇數,我們讓k也是奇數,然而因為k的序列變成(1,9,25,49,81,...),是嚴格遞增

所以我們可以找出一個適當的(k + 2)2 > M(一定找的到),然後M>=k2

當M是偶數也是用上面的作法。

 

現在我們找k的範圍

R[1], R[2], ..., R[k2], ..., R[M],...., R[(k + 2)2],....

雖然M不太可能會等於k2,不過如果等於的話

只要用M=k1+3+5+7+…+(2k-1)=k2,就可以解

因為M - k2一定是偶數,而且剛剛的假設是k2 < = M,我們可以讓M=k2+2r也就是M=x+2y

y就等於(M-k2)/2

所以我們可以到達R[k2],下一步是2k+1,然後k2 - ((2k + 1) + 2(y - 1)) > = 1,我們就可以到達R[M]

我們可以簡單的到達k2 因為1+3+5+7+…+(2k-1)=k2,也可以輕易地到達R[M],不過有條件

k2 - ((2k + 1) + 2(y - 1)) > = 1  y=(M-k2)/2

整理後變成

2k2 - 2k + 1 - M > = 1

而(k + 2)2 > M,加強限制條件的話2k2 - 2k + 1 - (k + 2)2 > = 1一定會讓2k2 - 2k + 1 - M > = 1

而2k2 - 2k + 1 - (k + 2)2 > = 1這個化減完就會變成k2 - 6k - 4 > = 0

解二元不等式k >= 6.7 > (6+sqrt(36+16))/2

而k2 < = M <= N,所以N>=49 就永遠都有解

沒有的話直接實做就好了

 

//====================================================================||
// Name : Gift.cpp ||
// Date : 2013/5/25 上午9:59:29 ||
// Author : GCA ||
// 6AE7EE02212D47DAD26C32C0FE829006 ||
//====================================================================||
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <climits>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <cctype>
#include <utility>
using namespace std;
#ifdef ONLINE_JUDGE
#define ll "%lld"
#else
#define ll "%I64d"
#endif
typedef unsigned int uint;
typedef long long int Int;
#define Set(a,s) memset(a,s,sizeof(a))
#define Write(w) freopen(w,"w",stdout)
#define Read(r) freopen(r,"r",stdin)
#define Pln() printf("\n")
#define I_de(x,n)for(int i=0;i<n;i++)printf("%d ",x[i]);Pln()
#define De(x)printf(#x"%d\n",x)
#define For(i,x)for(int i=0;i<x;i++)
#define CON(x,y) x##y
#define Pmz(dp,nx,ny)for(int hty=0;hty<ny;hty++){for(int htx=0;htx<nx;htx++){\
printf("%d ",dp[htx][hty]);}Pln();}
#define M 10011
#define PII pair<int,int>
#define PB push_back
#define oo INT_MAX
#define Set_oo 0x3f
#define Is_debug true
#define debug(...) if(Is_debug)printf("DEBUG: "),printf(__VA_ARGS__)
#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define eps 1e-6
bool xdy(double x,double y){return x>y+eps;}
bool xddy(double x,double y){return x>y-eps;}
bool xcy(double x,double y){return x<y-eps;}
bool xcdy(double x,double y){return x<y+eps;}
int min3(int x,int y,int z){
int tmp=min(x,y);
return min(tmp,z);
}
int max3(int x,int y,int z){
int tmp=max(x,y);
return max(tmp,z);
}
int n,m;
struct node{
int now;
int njump;
node(int now,int njump):now(now),njump(njump){};
};
bool bfs(){
queue<node> q;
q.push(node(1,3));
while(!q.empty()){
int now=q.front().now;
int njump=q.front().njump;
if(now==m)return true;
q.pop();
if(now+njump<=n)q.push(node(now+njump,njump+2));
if(now-njump>0)q.push(node(now-njump,njump+2));
}
return false;
}
int main() {
ios_base::sync_with_stdio(0);
while(~scanf("%d%d",&n,&m)&&n+m){
if(n>=49)printf("Let me try!\n");
else{
if(bfs())printf("Let me try!\n");
else printf("Don't make fun of me!\n");
}
}

















}

留言