题目描述如下:
说好了,题目不黑人。
给你一个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......output:
Case #1: Yes Case #2: No
本题就是一个BFS,这是因为每走一步,石头都会变化。而超过8步之后,所有的石头都不见了,只要小人还活着就能走出去。
想要处理每一步的时候迷宫状态不改变,就是用BFS。我将每一步都当做一个函数,将当前步小人可能存在的位置当做参数输入。
其中与网上题解不同的是,我认为在单步中不能出现两个重复的位置入队。否则一个多余的位置会导致倍时间消耗。加入单步去重后,效率提升了100倍左右。
请务必注意,case 的num是从1开始的,不是0!!
#include
#include
#include
using namespace std;
struct pos {
int x;
int y;
pos(int a, int b) {
x = a;
y = b;
};
pos() {};
bool equal(pos b) {
return (b.x == x && b.y == y);
}
};
char miGong[8][8];
int wx[9] = { 0,-1,0,1,-1,-1,1,1,0 };
int wy[9] = { -1,0,1,0,-1,1,1,-1,0 };
void debugMG() {
printf("\n");
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
printf("%c", miGong[i][j]);
}
printf("\n");
}
}
int judge(int x, int y) {
if (x<0 || x >7 || y<0|| y >7)return false;
if (miGong[x][y] == 'S')return false;
return true;
}
bool myBFS(int step, queue posQue) {
if (posQue.empty()) {//
return false;
}
if (step >= 8) return true;//第8步清空障碍,只要能活着就一定能安全到达
queuenowQue;
bool reached[8][8];
memset(reached, 0, sizeof(reached));
while (!posQue.empty()) {
pos before = posQue.front();
int nx = before.x, ny = before.y;
if (miGong[nx][ny] == 'S') {
//不应当返回
posQue.pop();//不在考虑从这里出发的情况
continue;
}
else {
for (int i = 0; i < 9; i++)
{
int new_x = nx + wx[i];
int new_y = ny + wy[i];
if (judge(new_x, new_y)&&reached[new_x][new_y]==0)
{
pos node = pos(new_x, new_y);
reached[new_x][new_y] = 1;
nowQue.push(node);
}
}
}
posQue.pop();
}
for (int i = 7; i >= 0;i--) {
for (int j = 0; j < 8; j++) {
if (miGong[i][j] == 'S') {
miGong[i][j] = '.';
if (i + 1 < 8) {
miGong[i+1][j] = 'S';
}
}
}
}//石头落下
//debugMG();
return myBFS(step + 1, nowQue);
}
int main() {
//freopen("output.txt", "w", stdout);
int t;
char thing;
scanf("%d", &t);
for (int i = 0; i < t; i++) {
getchar();
for (int m = 0; m < 8; m++) {
for (int n = 0; n < 8; n++) {
scanf("%c", &thing);
miGong[m][n] = thing;
}
getchar();//输入换行
}//input m*n
//BFS
queue posQue;
posQue.push(pos(7,0));
int step = 0;
bool cando = myBFS(step, posQue);
if (cando) {
printf("Case #%d: Yes\n", i+1);
}
else {
printf("Case #%d: No\n", i+1);
}
}
return 0;
}