说好了,题目不黑人。
给你一个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
#include
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 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
#include
#include
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 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;
}