POJ 3278 Catch That Cow

来源:互联网 发布:淘宝新店如何提升信誉 编辑:程序博客网 时间:2024/05/18 00:38
题意: 给定两个整数n和k

通过 n+1或n-1 或n*2 这3种操作,使得n==k

输出最少的操作次数

思路:   3个方向的BFS【+1,-1,*2】

注意:  因为数据比较大,直接套模板BFS会TLE,

应该适当剪枝:

1,当n>=k时,直接可知最少步数n-k【只能通过后退一步来到达位置k】

如果此处进入BFS则会浪费很多时间!

2,如果BFS到当前位置大于k,那么以后的+1都不会到达小牛的位置。

也只能通过后退一步的方式来达到k,所以当当前位置大于k是不需要

继续判断+1的情况了。

3,同2,如果当前位置比k还大,也是只能通过后退的方式达到k,

所以*2的情况也不用考虑。


/*POJ 3278问题1186Memory 5400Time 1420*/#include<iostream>#include<cstring>#include<queue>#include<stdio.h>using namespace std;const int MAXN = 1000050;int vis[MAXN+1];int n, k;struct Node{int x, step;};int bfs(int start){memset(vis, 0, sizeof(vis));queue<Node>Q;Node temp;temp.x = start;temp.step = 0;vis[temp.x] = 1;Q.push(temp);while (!Q.empty()){Node h;h = Q.front();Q.pop();if (h.x == k){return h.step;}if (h.x + 1 <= k&&vis[h.x + 1] == 0)//剪枝,如果当前位置大于k,{                            //那么以后的+1都不会到达小牛的位置。Node next;vis[h.x + 1] = 1;next.x = h.x + 1;next.step = h.step + 1;Q.push(next);}if (h.x - 1 >= 0 && vis[h.x - 1] == 0){Node next;vis[h.x - 1] = 1;next.x = h.x - 1;next.step = h.step + 1;Q.push(next);}if ((h.x <= k)&&(h.x * 2 <= MAXN) && vis[h.x * 2] == 0){                            //如果当前位置比k还大那么下一次*2会更大Node next;              //后退只能-1,那么本来就比k大,那么可以后退vis[h.x * 2] = 1;       //(当前位置步-k步),而再*2那就得后退(当前位置*2-k步)next.x = h.x * 2;            next.step = h.step + 1;Q.push(next);}}return 0;}int main(){while (scanf("%d %d",&n,&k)!=EOF){if (n >= k)//剪枝,当n大于k时,n只能通过后退{          //一步来达到k,不需要进入bfs,不然会TLEcout << n - k << endl;}else{printf("%d\n", bfs(n));}}return 0;}


0 0