博客书写参考(格式不熟练啊
原题链接:https://vjudge.net/contest/65959;jsessionid=8F1D7A25C9ACBE20A5663D1837797F78#problem/C
PS:bfs入门题目。
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 32679 | Accepted: 10060 |
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
Source
FJ要抓奶牛。
开始输入N(FJ的位置)K(奶牛的位置)。
FJ有三种移动方法:1、向前走一步,耗时一分钟。
2、向后走一步,耗时一分钟。
3、向前移动到当前位置的两倍N*2,耗时一分钟。
问FJ抓到奶牛的最少时间。PS:奶牛是不会动的。
#include<stdio.h> #include<iostream> #include<queue> #include<string.h> using namespace std; int N, K; struct Node{ int x; int temp; }; struct Node quee[300000]; //int dir[2][2] = { -1,0, 1,0 }; int dir[2] = { -1,1 }; int viv[300000]; int map[300000]; void bfs(void); int tomap(int x); int q, next; int main() { while(scanf("%d%d", &N, &K) != EOF) { q = 0; next = 1; memset(viv, 0, sizeof(viv)); viv[N] = 1; if(N == K) printf("0\n"); else if(N > K) printf("%d\n", N - K); else bfs(); } return 0; }
void bfs(){ int con = 0; int i, dx; int thisx; quee[q].x = N; quee[q].temp = 0; while(next >= q) { thisx = quee[q].x; for(i = 0; i < 3; i++) { if(i != 2) dx = thisx + dir[i]; else if(i == 2) dx = 2 * thisx; if(tomap(dx)) continue; viv[dx] = 1; quee[next].temp = quee[q].temp + 1; quee[next++].x = dx; if(dx == K){ printf("%d\n", quee[q].temp + 1); return; } } q++; } return;}
C++ 队列 + bfs :
#include<stdio.h> #include<iostream> #include<queue> #include<string.h> using namespace std; int N, K; struct Node{ int x; int temp; }; int dir[2] = { -1,1 }; int viv[200001]; void bfs(void); int tomap(int x); int q;//, next; int main() { while(scanf("%d%d", &N, &K) != EOF) { q = 0; next = 1; memset(viv, 0, sizeof(viv)); viv[N] = 1; if(N == K) printf("0\n"); else if(N > K) printf("%d\n", N - K); else bfs(); } return 0; } int tomap(int x) { if(viv[x] == 1) return 1; if(x < 0 || x > 100001) return 1; return 0; } void bfs() { int i; queue<Node>Q; Node a, next; a.x = N; a.temp = 0; Q.push(a); while(!Q.empty()) { a = Q.front(); Q.pop(); for(i = 0; i < 3; i++) { if(i != 2) next.x = a.x + dir[i]; else if(i == 2) next.x = 2 * a.x; if(tomap(next.x)) continue; viv[next.x] = 1; // printf("%d %d\n", next.x, next.temp); next.temp = a.temp + 1; if(next.x == K){ printf("%d\n", a.temp + 1); return; } Q.push(next); } } return; }
这里有几点需要注意,我的提交RE->WA->AC
其中注意数组开的大一点(我开的三十万),但是期间没有注意到,有2*x会变到大于K的情况,所以这里广搜的时候可能会有一个数据正准备存储,却以为乘以二而变得超过了int的范围?(我是这样理解的),这时就会运行都没运行结束而退出,所以会RE,
发现之后果断将这个存储数据的变量做一个剪枝(我没写过什么剪枝,姑且这么叫吧),就是当数据变量大于K的2倍(可以再大,但不能再小了)的时候就返回,这下可以避免RE啦。
接下来WA了,
想去学一下暴力对拍(奇技淫巧),想想神乎其神的LBC徒手各种AC,我还是暂时算了吧,(蓝桥杯国二,然而一点没有傲气,二哥每天帮助室友各种完成作业,欸。更甚的是看不到他什么时候学的习,每天HUOZAITADEYINYINGZHIXIA)。随手测试了几个数据,发现当N>K的 时候会出问题,果断吧N>K的时候单独写了一下,AC了。想想还是挺简单的。我居然花了好几天。。。
我这么弱还活在世界上真的对不起。日夜受火焚之苦。。我被黑暗吞噬了,地球的空气无时无刻不在腐蚀着我。
梦寐已久的是像正常人一样行为,思考。。。人类可怕的眼神。莫名的嫌弃自己,这样下去会死掉的啊。。。acm抹去我噩梦般的记忆。。。
像二哥这种不需要刷多少题目,就是靠自己聪明自创各种算法,还谦虚的说自己是靠运气。。我真是拜倒在二哥脚下啊
教我做人。。。
我这么丑的代码打算看看dalao的博客学习改进一下传送门(超级赞)。