题目:http://acm.hdu.edu.cn/showproblem.php?pid=2717
本题大意:一个农民John在坐标N处,他的牛在坐标K处。他要去抓这头牛,现在他有两种接近的方法
1、从 X 到 X+1 或 X-1(需要一分钟时间)。
2、从 X 到 2*X。(需要一分钟时间)。
问:最少需要多少时间抓到牛?
搜索就是从一种状态转移到另一种状态。在本题中我们是从一个位置转移到另一个位置,而且我们只需要知道最近的方式。那么我们应该优先扩展多有可能的状态,也就是BFS(宽度优先搜索)。换而言之就是先横向搜索在纵向搜,这样就和树一样一层层的往下走(不知道树的同学可以结合,可以参照:这里 来了解什么是树)。只要其中任意一种方法到达终点,那么我们就结束搜索。这时我们就得到了最短时间的路径。
下面就是代码+注释:
#include <iostream>
#include <string.h>
#include <queue>
#define MAXN 100000+10
using namespace std;
int start,goal; //start为起始坐标,goal为牛的坐标
int record[2*MAXN]; //用于记录到各个位置的时间
queue<int> Q;
int Move(int x,int a){ //位移参量
if(a==0)
return x-1;
else if(a==1)
return x+1;
return 2*x;
}
int BFS(){
int now,next,i;
while(!Q.empty()) //队列初始化
Q.pop();
now=start;
Q.push(now); //将起点加入队列Q
while(!Q.empty()){ //直到队列长度为零,循环停止
now=Q.front(); //从队列中取出最前端元素
Q.pop();
if(now==goal) break; //如果当前状态,已经达到终点,则结束搜索
for(i=0;i<3;i++){
next=Move(now,i); //三种方式的位移
if(record[next]==0&&next>=0&&next<MAXN){
//判断是否该点是否访问过
record[next]=record[now]+1;
//可以移动的话,则时间+1
Q.push(next);
}
}
}
return record[goal];
}
int main(){
while(cin>>start>>goal){
memset(record,0,sizeof(record));
//将时间初始化
cout<<BFS()<<endl;
}
return 0;
}