本题本身的难度并不大,只要转换一下思维,将不同位置的格子移动想象成为只有空白格子在不断移动即可。本题复杂的地方在于输入输出的格式以及数组可能会越界的问题。(一定要仔细检查!debug三天才发现!!血的教训!!)
- 输入的格式要注意不能使用cin或者scanf,它们在遇到空格的时候会停止读入,导致空格后的字符无法写入数组,最终造成结果错误。我在代码中使用的是gets()函数。
- 输出时候要注意两个地方:一是空格的位置不是每一个样例之后,而是出了第一个样例之外的所有样例之前(即最后一个样例之后不能有空行);而是样例中最后一个字符后没有空格。
- 数组越界的问题,一定要先判断再决定是否写入。
题目链接:UVa 227
AC代码:
#include <iostream>
#include <string>
#include <string.h>
using namespace std;
char s[5][7];
const char* opre = "ABRL";
char op[100001]; //存放代表各种操作的字符
int main() {
int k, n = 0, len = 0;
char c;
while (gets(s[0])) {
memset(op, 0, sizeof(op));
int x = -1, y = -1;
if (s[0][0] == 'Z') //判断第一个读入的字符,如果是'Z'则退出程序。
break;
for (int i = 1; i <= 4; i++)
gets(s[i]);
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++)
if (s[i][j] == ' ') {
x = i;
y = j; //存储空格字符所在位置
break;
}
if (x >= 0 && y >= 0)
break;
}
int m = 0;
while (cin >> op[m]) {
if (op[m] != '0')
m++;
else break;
}
op[m] = 0; getchar(); //吞掉最后的换行符
if (n++)
cout << endl; //除了第一个样例外都要输出空行
cout << "Puzzle #" << n << ":" << endl;
for (k = 0; op[k]; k++) {
if (op[k] == opre[3] && (y - 1) >= 0) {
s[x][y] = s[x][y - 1];
s[x][--y] = ' ';
}
else if (op[k] == opre[2] && (y + 1) <5) {
s[x][y] = s[x][y + 1];
s[x][++y] = ' ';
}
else if (op[k] == opre[1] && (x + 1) <5) {
s[x][y] = s[x + 1][y];
s[++x][y] = ' ';
}
else if (op[k] == opre[0] && (x - 1) >= 0) {
s[x][y] = s[x - 1][y];
s[--x][y] = ' ';
}
else {
cout << "This puzzle has no final configuration." << endl;
break;
}
}
if (k == m) {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (j == 4)
cout << s[i][j];
else
cout << s[i][j] << " ";
}
cout << endl;
}
}
}
return 0;
}