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 }

 

 

posted @ 2013-05-04 06:41  ~~Snail~~  阅读(208)  评论(0编辑  收藏  举报