初识BFS POJ-3278 Catch That Cow FZU-2285 迷宫寻宝
-
令人窒息的创新实验课让我们写程序。
-
POJ-3278 Catch That Cow
-
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
Line 1: Two space-separated integers: N and K
-
Output
Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.
-
Sample Output
5 17
-
Hint
The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.
-
我的题解
#include <iostream> #include <queue> using namespace std; #define maxn 100001 int step[maxn]; //代表到达每个位置需要的步数 bool visit[maxn]; //代表某个位置是否被访问 queue<int> q; int BFS(int N, int K) { int head, next; step[N] = 0; visit[N] = true; q.push(N); while (!q.empty()) { head = q.front(); q.pop(); for (int i = 0; i < 3; i++) { if (i == 0) //代表往左1 next = head - 1; if (i == 1) //代表往右1 next = head + 1; if (i == 2) //代表乘2 next = head * 2; if (next < 0 || next > maxn) //排除越界的情况 continue; if (!visit[next]) { q.push(next); //加入队列中,下次作为head弹出,准备下一轮搜索 visit[next] = true; step[next] = step[head] + 1; //head表示前一个点,next表示后一个点,两者的步数当然差1 } if (next == K) return step[next]; } } return 0; //代表找不到(大概,应该都会找到吧 } int main() { int N, K; //N是John初始的位置,K是牛的位置 cin >> N >> K; if (N - K >= 0) cout << N - K << endl; else cout << BFS(N, K) << endl; return 0; }
-
然后是第二题 FZU-2285
洪尼玛今天准备去寻宝,在一个n*n (n行, n列)的迷宫中,存在着一个入口、一些墙壁以及一个宝藏。由于迷宫是四连通的,即在迷宫中的一个位置,只能走到与它直接相邻的其他四个位置(上、下、左、右)。现洪尼玛在迷宫的入口处,问他最少需要走几步才能拿到宝藏?若永远无法拿到宝藏,则输出-1。
-
Input
多组测试数据。 每组数据输入第一行为正整数n,表示迷宫大小。 接下来n行,每行包括n个字符,其中字符'.'表示该位置为空地,字符'#'表示该位置为墙壁,字符'S'表示该位置为入口,字符'E'表示该位置为宝藏,输入数据中只有这四种字符,并且'S'和'E'仅出现一次。 n≤1000
-
Output
输出拿到宝藏最少需要走的步数,若永远无法拿到宝藏,则输出-1。
-
Sample Input
5 S.#.. #.#.# #.#.# #...E #....
-
Sample Output
7
-
我的题解
#include <iostream> #include <queue> #include <cstring> using namespace std; #define maxn 1000 bool visit[maxn][maxn]; int step[maxn][maxn]; typedef struct { int i; //代表节点的横坐标 int j; //纵坐标 } node; queue<node> q; //定义一个节点为node的队列 int BFS(char **maze, int n, node start, node end) { visit[start.i][start.j] = true; step[start.i][start.j] = 0; q.push(start); //关于起点的初始化 node head, next; //在过程中分别指代现在的位置和下一个位置 while (!q.empty()) { head = q.front(); q.pop(); for (int i = 0; i < 4; i++) { if (i == 0) //代表往左 next.i = head.i - 1, next.j = head.j; if (i == 1) //代表往右 next.i = head.i + 1, next.j = head.j; if (i == 2) //代表往上 next.i = head.i, next.j = head.j - 1; if (i == 3) //代表往下 next.i = head.i, next.j = head.j + 1; if (next.i < 0 || next.i >= n || next.j < 0 || next.j >= n || maze[next.i][next.j] == '#') //越界或者碰到墙壁的情况排除 continue; if (!visit[next.i][next.j]) { visit[next.i][next.j] = true; step[next.i][next.j] = step[head.i][head.j] + 1; //next的步数比head的步数+1 q.push(next); } if (maze[next.i][next.j] == 'E') return step[next.i][next.j]; } } return -1; } int main() { int n; //表示迷宫的大小 while (cin >> n) { memset(visit, false, sizeof(visit)); memset(step, 0, sizeof(step)); while (!q.empty()) q.pop(); char **maze = new char *[n]; //动态创建二维数组maze for (int i = 0; i < n; i++) maze[i] = new char[n]; node start, end; //分别代表起点和终点,用来储存他们的坐标 for (int i = 0; i < n; i++) scanf("%s", maze[i]); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { if (maze[i][j] == 'S') start.i = i, start.j = j; if (maze[i][j] == 'E') end.i = i, end.j = j; } cout << BFS(maze, n, start, end) << endl; } return 0; }
-
水博客,逃(