程序设计基础8 广度优先搜索BFS

题目描述

说好了,题目不黑人。

给你一个8*8的矩阵,你的初始位置是左下角方格(用'U’表示),你的目标位置是右上角的方格(用'A'表示),其余的62个方格,如果是'.',表示这个方格为空,如果是'S',表示这个方格有一块大石头。好了现在你开始从左下角出发,每次可以往上,下,左,右,左上,右上,左下,右下移动一个方格,或者你可以原地不动,一共九个动作方式,在你做完一个动作后,所有的大石头会往下掉一个方格(如果一个大石头的位置是(x,y),那下一秒是(x+1,y),不过如果它已经在最下面的一排了,那它就会掉出矩阵,不再出现),请注意,任一时刻,你不能和某一个大石头处在同一个方格,否则石头会把你XX掉。

现在的问题就是:你能从左下角安全抵达右上角么? 如果能,输出“Yes”,反之,“No”。

输入

T->测试数据组数(T)。

对于每组数据,输入一个8*8的矩阵,其后有一空行。描述如上。

输出

对于第i组数据,请输出

Case #i: s(s是一个字符串,如果可以到达,则s为“Yes”,反之“No”)

样例输入

2
.......A
........
........
........
........
........
........
U.......

.......A
........
........
........
........
.S......
S.......
US......

样例输出

Case #1: Yes
Case #2: No

1,表示问题:

    之前的想法:在输入地图的时候同时构造出一个表示石块是否存在的二维数组,每次走一步的同时每一行向下平移一个,已经走过的那几行全部置一,这种方法很麻烦。

    正确想法:只考虑每行序号x,有这样两个公式:

    a,石块所在的x + 走之后的步数 = 走之后所在的x,表示石块在将要走的位置的头顶,即不可走,移项即是:走之后所在的x - 走之后的步数 = 石块所在的x

    b,石块所在的x + 走之后的步数 = 走之后的x + 1,表示石块在将要走的那个位置,即不可走,移项即是:走之后的x - 走之后的步数 + 1 = 石块所在的x

2,关于输入问题:

    之前的做法:虽然可以横纵坐标从1开始,但是这种方法总是出错,故暂时抛弃不用。

for (int j = 1; j <= 8; j++) {
    for (int k = 1; k <= 8; k++) {
	mapping[j][k] = getchar();
    }
    getchar();
}

    正确的做法:

for (int j = 0; j < 8; j++) {
    scanf("%s", &mapping[j]);
}

3,关于BFS算法问题:

    正确的答案是先把将要走的那一步,包括走那一步后的步数暂存起来,注意,是用结构体暂存起来,不是用newX,newY这种变量暂存起来了,不管你走还是不走,反正是暂存,不能走下一个可以把它改了。

for (int i = 0; i < 9; i++) {
    temp.x = top.x + x_adjust[i];
    temp.y = top.y + y_adjust[i];
    temp.step = top.step + 1;                         //先把这将来的一步弄好,包括这一步的计数
    if (check(temp.x, temp.y) == 1 && mapping[temp.x - temp.step][temp.y] != 'S' && mapping[temp.x - temp.step + 1][temp.y] != 'S') {
        if (mapping[temp.x][temp.y] == 'A' || temp.step >= 8) {
		return 1;
	}
	que.push(temp);
    }
}

二,我的错误解法:

#include<cstdio>
#include<queue>
using namespace std;
//到15:15
char mapping[11][11];
int stone[20][20] = { 0 };
int stone_1[20][20] = { 0 };
int x_adjust[8] = { -1,1,0,0,-1,-1,1,1 };
int y_adjust[8] = { 0,0,-1,1,-1,1,-1,1 };
struct Point {
	int x;
	int y;
	int step;
}point;
queue<Point> que;
int check(int x, int y,int array[][20]) {
	if (x > 8 || x <= 0 || y > 8 || y <= 0) {
		return 0;
	}
	if (array[x][y] == 1 || array[x - 1][y] == 1) {
		return 0;
	}
	return 1;
}
int BFS(int x, int y) {
	point.x = x;
	point.y = y;
	point.step = 0;
	que.push(point);
	while (!que.empty()) {
		Point top = que.front();
		que.pop();
		int newX = top.x;
		int newY = top.y;
		int old_step = top.step;
		if (old_step == 8) {
			return 1;
		}
		for (int i = 1; i <= 8; i++) {
			for (int j = 1; j <= 8; j++) {
				stone_1[i + old_step][j] = stone[i][j];
			}
		}
		for (int i = 1; i <= old_step; i++) {
			for (int j = 1; j <= 8; j++) {
				stone_1[i][j] = 0;
			}
		}
		for (int i = 0; i < 8; i++) {
			newX = top.x + x_adjust[i];
			newY = top.y + y_adjust[i];
			if (check(newX, newY, stone_1)) {
				if (newX == 1 && newY == 8)return 1;
				point.x = newX;
				point.y = newY;
				point.step = old_step + 1;
				que.push(point);
			}
		}
	}
	return 0;
}
int main(){
	int num = 0;
	int answer = 0;
	scanf("%d", &num);
	char a = getchar();
	for (int i = 0; i < num; i++) {
		while (!que.empty())que.pop();
		stone_1[20][20] = { 0 };
		for (int j = 1; j <= 8; j++) {
			for (int k = 1; k <= 8; k++) {
				mapping[j][k] = getchar();
				if (mapping[j][k] == 'S') {
					stone[j][k] = 1;
				}
			}
			getchar();
		}

		for (int x = 1; x <= 8; x++) {
			for (int y = 1; y <= 8; y++) {
				stone_1[x][y] = stone[x][y];
			}
		}
		answer = BFS(8, 1);
		printf("Case #%d: ", i+1);
		if (answer == 1) printf("Yes\n");
		else printf("No\n");
		if (i != num - 1)getchar();
	}
	return 0;
}

三,正确代码:

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
char mapping[11][11];
int x_adjust[9] = { -1,1,0,0,-1,-1,1,1,0 };
int y_adjust[9] = { 0,0,-1,1,-1,1,-1,1,0 };
struct Point {
	int x;
	int y;
	int step;
}point, temp;
int check(int x, int y) {
	if (x >= 8 || x < 0 || y >= 8 || y < 0) {                               //日掉你,草泥马,这里出了大错
		return 0;
	}
	return 1;
}
int BFS(int x, int y) {
	queue<Point> que;
	point.x = x;
	point.y = y;
	point.step = 0;
	que.push(point);
	while (!que.empty()) {
		Point top = que.front();
		que.pop();
		for (int i = 0; i < 9; i++) {
			temp.x = top.x + x_adjust[i];
			temp.y = top.y + y_adjust[i];
			temp.step = top.step + 1;                               //先把这将来的一步弄好,包括这一步的计数
			if (check(temp.x, temp.y) == 1 && mapping[temp.x - temp.step][temp.y] != 'S' && mapping[temp.x - temp.step + 1][temp.y] != 'S') {
				if (mapping[temp.x][temp.y] == 'A' || temp.step >= 8) {
					return 1;
				}
				que.push(temp);
			}
		}
	}
	return 0;
}
int main(){
	int num = 0;
	int answer = 0;
	scanf("%d", &num);
	getchar();
	for (int i = 0; i < num; i++) {
		for (int j = 0; j < 8; j++) {
			scanf("%s", &mapping[j]);
		}
		answer = BFS(7, 0);
//		printf("Case #%d: ", i+1);
		if (answer == 1)
		{
			cout << "Case #" << i + 1 << ": Yes" << endl;
		}
		else
			cout << "Case #" << i + 1 << ": No" << endl;
//		if (i != num - 1)getchar();
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq2285580599/article/details/82424814