http://poj.org/problem?id=3278
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 52463 | Accepted: 16451 |
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
Output
Sample Input
5 17
Sample Output
4
Hint
1 #include <fstream> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 #include <cmath> 7 #include <cstdlib> 8 #include <queue> 9 10 using namespace std; 11 12 #define PI acos(-1.0) 13 #define EPS 1e-10 14 #define lll __int64 15 #define ll long long 16 #define INF 0x7fffffff 17 18 queue<pair<int,int> > qu; 19 bool b[100002]; 20 21 inline bool Check(int x); 22 int Bfs(int r1,int r2); 23 24 int main(){ 25 //freopen("D:\\input.in","r",stdin); 26 //freopen("D:\\output.out","w",stdout); 27 int r1,r2; 28 scanf("%d %d",&r1,&r2); 29 printf("%d\n",Bfs(r1,r2)); 30 return 0; 31 } 32 inline bool Check(int x){ 33 return x>=0&&x<=100000&&b[x]==0; 34 } 35 int Bfs(int r1,int r2){ 36 qu.push(make_pair(r1,0)); 37 b[r1]=1; 38 while(!qu.empty()){ 39 pair<int,int> tmp=qu.front(); 40 qu.pop(); 41 if(tmp.first==r2){ 42 return tmp.second; 43 } 44 int x=tmp.first+1; 45 if(Check(x)){ 46 b[x]=1; 47 qu.push(make_pair(x,tmp.second+1)); 48 } 49 x=tmp.first-1; 50 if(Check(x)){ 51 b[x]=1; 52 qu.push(make_pair(x,tmp.second+1)); 53 } 54 x=tmp.first*2; 55 if(Check(x)){ 56 b[x]=1; 57 qu.push(make_pair(x,tmp.second+1)); 58 } 59 } 60 }
我自己底下实验了下,把STL去掉,自己实现简易的队列,再进行暴搜,时间消耗为16ms。
代码二:【0ms】bfs剪枝(这里没有用STL): 剪枝内容:当自己的位置大于k的时候,自然不用考虑+1和*2的情况了。
1 #include <fstream> 2 #include <iostream> 3 #include <cstdio> 4 5 using namespace std; 6 7 const int N=100005; 8 int n,k,dis[N],queue[N];//dis:记录走到某个点的步数。 queue:因为每次队列采用去重加入,所以N是足够用了。 9 bool b[N];//N是足够的,不需要扩展2N或者3N。打比说x先乘再减,与先减再乘,后者会更快,故不会超过N,负数是更不可能的,因为没有除法。 10 11 int bfs(); 12 13 int main() 14 { 15 //freopen("D:\\input.in","r",stdin); 16 //freopen("D:\\output.out","w",stdout); 17 scanf("%d%d",&n,&k); 18 printf("%d",bfs()); 19 return 0; 20 } 21 int bfs(){ 22 int l,r,x; 23 l=r=0; 24 dis[n]=0; 25 queue[0]=n; 26 while(1){//队列不可能为空 27 if(queue[l]==k) return dis[k]; 28 if(x=queue[l]-1,x>=0&&!b[x]){//注意边界 29 b[x]=1; 30 queue[++r]=x; 31 dis[x]=dis[queue[l]]+1; 32 } 33 if(x=queue[l]+1,queue[l]<=k&&!b[x]){//这里的queue[l]<=k为剪枝 34 b[x]=1; 35 queue[++r]=x; 36 dis[x]=dis[queue[l]]+1; 37 } 38 if(x=queue[l]<<1,queue[l]<=k&&x<N&&!b[x]){//这里的queue[l]<=k为剪枝;注意边界 39 b[x]=1; 40 queue[++r]=x; 41 dis[x]=dis[queue[l]]+1; 42 } 43 l++; 44 } 45 }