POJ3278:Catch That Cow——BFS
题目描述
Farmer John从n位置出发,去找k位置的牛,每一步需要花费1minute,每一步可选的方式如下:
- 走到n+1
- 走到n -1
- 走到2*n
求FJ找到牛所需要的最短时间
搜索:初始状态经过一系列状态转变到达目标状态
状态空间:<位置,时间>
状态转换:<n+1,t+1>、<n-1,t+1>、<n*2,t+1>
初始状态:<n,0>
目标状态:<k,t>
搜索策略:BFS(广度优先搜索)、DFS(深度优先搜索)
BFS中一层一层地进行搜索,而每一层(相当于每走一步)所花时间就要+1,要求花费时间最小,因此使用BFS
算法思路
- 初始化visit数组
- 起始状态访问入队
- 取出队首状态,求其转换状态,并判断是否合法,访问入队
- 重复3,直到队列为空
注意:要判断新状态是否合法
#include<iostream>
#include<cstdio>
#include<queue>
#include<string.h>
using namespace std;
const int MAXN = 1E5 + 10;
struct Status{
int pos;
int time;
Status(int p, int t): pos(p), time(t){}
};
bool visit[MAXN];
int BFS(int n, int k){
queue<Status> q;
q.push(Status(n, 0)); //压入初始状态
visit[n] = true; //起点已访问
int ans = 0;
while(!q.empty()){
Status current = q.front();
q.pop();
if(current.pos == k){ //查找成功
ans = current.time;
break;
}
for(int i = 0; i < 3; ++i){ //3种状态转换
Status nextStatus = current;
if(i == 0){
nextStatus.pos -= 1;
}
else if(i == 1){
nextStatus.pos += 1;
}
else{
nextStatus.pos *= 2;
}
++nextStatus.time;
if(nextStatus.pos < 0 || nextStatus.pos > 1e5 || visit[nextStatus.pos]){
continue; //新状态不合法
}
q.push(nextStatus); //压入新状态
visit[nextStatus.pos] = true; //该结点已访问
}
}
return ans;
}
int main(){
int n, k;
scanf("%d%d", &n, &k);
memset(visit, false, sizeof(visit));
printf("%d\n", BFS(n, k));
return 0;
}