博客书写参考(格式不熟练啊
原题链接: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的博客学习改进一下传送门(超级赞)。