Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 75706 | Accepted: 23901 |
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
分析:该题是BFS入门题,对于理解BFS有挺大的帮助。使用广度优先搜索对每一步的情况处理放入队列。该题在BFS的基础上还需要进行剪枝,否则会出现超时。具体剪枝可参见AC代码:
#include<stdio.h>
#include<queue>
#include<map>
#include<math.h>
#include<string.h>
using namespace std;
const int maxn=100005;
//map<int,bool>vis; //使用map存储 用数组的话 大数无法确定区间
int vis[maxn];
int n,k;
struct ele
{
int num,step;
};
void BFS()
{
vis[n]=true;
queue<ele> q;
ele e;
e.num=n;
e.step=0;
q.push(e); //设置初始值
while(!q.empty())
{
ele f=q.front();//队列初始值判定
if(f.num==k)
{
printf("%d\n",f.step);
break;
}
q.pop(); //队列首出队列
ele temp;
if(f.num-1>=0&&!vis[f.num-1]) //第二种情况 若原来的值已经大于k 那么加一毫无意义
{
//千万不能写成 if(!vis[f.num-1]&&f.num-1>=0) 会导致数组出界
temp.num=f.num-1;
temp.step=f.step+1;
q.push(temp);
vis[temp.num]=1;
}
if(f.num+1<=maxn&&!vis[f.num+1]) //第一种情况
{
temp.num=f.num+1;
temp.step=f.step+1;
q.push(temp);
vis[temp.num]=1;
}
if(f.num*2<maxn&&!vis[f.num*2]) //第三种情况 若原来的值已经大于k 那么乘以2毫无意义
{
temp.num=f.num*2;
temp.step=f.step+1;
q.push(temp);
vis[temp.num]=1;
}
}
return ;
}
int main()
{
while (~scanf("%d%d",&n,&k))
{
memset(vis,0,sizeof(vis));
BFS();
}
}
该题代码笔者在书写时出现了数组溢出的错误。费了好大力气最终找到了bug,产生原因是在向队列中加入元素的时候应该先进行边界判断后进行访问性判断,若先进行访问行判断的话就会导致数组越界,&&符号的机制是前面如果错误,则后面判断条件不进行判断所以先判断边界后判断访问性就不会产生错误。
有思路和写出AC的代码还是两个概念,只有真正动手写下来才能发现和解决问题。
特记下,以备后日回顾。