POJ 3278 Catch That Cow
Catch That Cow
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 35330 | Accepted: 10888 |
Description
Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.
* Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute * Teleporting: FJ can move from any point X to the point 2 × X in a single minute.
If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?
Input
Line 1: Two space-separated integers: N and K
Output
Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.
Sample Input
5 17
Sample Output
4
Hint
The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.
昨天写的BFS一直不对,今天早上仔细检查了一下,发现是自己剪枝没处理好,把有最少步骤的枝剪掉了,囧……
之前写了一个在读入n以后,如果2*n<k就自动n*=2,后来发现这样并不是最快的,很有可能最后剩下一个很长的路只能一步一步+1
所以“退一步海阔天空”很重要~~
下面是我写的代码(第一次做BFS,之前只在刘汝佳的书上学过一次BFS)
[C++]
1 #include<iostream> 2 #include<queue> 3 #include<cstdio> 4 5 using namespace std; 6 7 long step[100001]; 8 long n,k; 9 queue<int> q; 10 11 int main() 12 { 13 cin>>n>>k; 14 if(n>k) 15 cout<<n-k<<endl; 16 else 17 { 18 q.push(n); 19 while((!q.empty())&&q.front()!=k) 20 { 21 int z; 22 //首先判断z的范围是不是越界,如果不越界再继续判断后面的条件:如果step[z]还没有被赋值过值(即step[z]==0),就把这次的步数赋进去(这里需要注意step[n]原本就是0),如果已经付过值且比这次的大,就把这个新算出来的小的赋进去 23 if(((z=q.front()-1)>=1)&&((z!=n&&step[z]==0)||(step[z]>(step[q.front()]+1)))) 24 { 25 step[z]=step[q.front()]+1; 26 if(z==k) 27 break; 28 else 29 q.push(z); 30 } 31 if(((z=q.front()+1)<=100000)&&((z!=n&&step[z]==0)||(step[z]>(step[q.front()]+1)))) 32 { 33 step[z]=step[q.front()]+1; 34 if(z==k) 35 break; 36 else if(z<k) 37 q.push(z); 38 else 39 for(int x=z-1,y=1;x>=k;x--,y++) 40 if((x!=n&&step[x]==0)||step[x]>step[z]+y) 41 step[x]=step[z]+y; 42 } 43 if(((z=q.front()*2)<=100000)&&((z!=n&&step[z]==0)||(step[z]>(step[q.front()]+1)))) 44 { 45 step[z]=step[q.front()]+1; 46 if(z==k) 47 break; 48 else if(z<k) 49 q.push(z); 50 else 51 { 52 //如果z>k就只能一步一步退回去了,所以不需要入队,只需一个一个退回去就能算出步骤 53 for(int x=z-1,y=1;x>=k;x--,y++) 54 if((x!=n&&step[x]==0)||step[x]>(step[z]+y)) 55 step[x]=step[z]+y; 56 } 57 } 58 q.pop(); 59 } 60 61 cout<<step[k]<<endl; 62 } 63 64 return 0; 65 }