题目链接:http://poj.org/problem?id=3278
题意:
在一个数轴上(0 ~ 100000),给你农夫J的位置N,和牛cow的位置K,农夫有三种移动的方式:左移一步(X - 1,X为当前位置);右移一步(X + 1);右移2*X步(2 * X);问农夫最少移动多少步可以追赶到牛,牛是原地不动的.
思路:
既然问的是最少移动多少步,最容易想到的就是暴力了,假设从起点开始每步有三个选择,选择一个点之后,接下来还是有三种选择.......这样就构造了一颗完全三叉树,即问题的解空间.由于问题问得是最短距离,即尽可能浅的访问到这棵树中的目标点.很明显的采用BFS就好了~
注意:
点的下界是 0,上界是 100000,所以BFS时判断点是否访问之前,应该先判断点是否在界限之内.单纯的吃了四五发RE......
代码:
1 #include <iostream> 2 #include <cmath> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <stack> 7 #include <queue> 8 #include <vector> 9 #include <algorithm> 10 #include <string> 11 12 typedef long long LL; 13 using namespace std; 14 const int MAXN = 100000; 15 int visit[MAXN + 3];//标记数组 16 int FJ, cow; 17 18 typedef struct Point { int x; int step; } Poi; 19 20 int check(int k) {//判断点是否在界限之内 21 if(k >= 0 && k <= MAXN) return 1; 22 return 0; 23 } 24 25 int BFS(Poi st) {//从农夫的起始点开始搜索解答树 26 queue<Poi> Qu; 27 Qu.push(st); 28 visit[st.x] = 1; 29 int ans = -1; 30 while(!Qu.empty()) { 31 Poi now; 32 now = Qu.front(); 33 Qu.pop(); 34 ans = now.step; 35 if(now.x == cow) break;//到达目标点 36 if(check(now.x + 1) && !visit[now.x + 1]) {//先判断点的范围再判断是否访问, 三个 if 分别为三种移动方式 37 Poi nex; 38 nex.x = now.x + 1, nex.step = now.step + 1; 39 Qu.push(nex); 40 visit[nex.x] = 1; 41 } 42 if(check(now.x -1) && !visit[now.x - 1]) { 43 Poi nex; 44 nex.x = now.x - 1, nex.step = now.step + 1; 45 Qu.push(nex); 46 visit[nex.x] = 1; 47 } 48 if(check(now.x * 2) && !visit[now.x * 2]) { 49 Poi nex; 50 nex.x = now.x * 2, nex.step = now.step + 1; 51 Qu.push(nex); 52 visit[nex.x] = 1; 53 } 54 } 55 return ans; 56 } 57 58 int main() { 59 while(~scanf("%d%d", &FJ, &cow)) { 60 memset(visit, 0, sizeof(visit)); 61 Poi st; 62 st.x = FJ, st.step = 0; 63 printf("%d ", BFS(st)); 64 } 65 return 0; 66 }