题目链接:https://www.luogu.com.cn/problem/UVA227
Puzzle
这道题目一上来一大堆题目描述,还是英文,对于我这样的英文不怎么样的人直接劝退,还好看了一下中文翻译,豁然开朗,题目的大意是:有5*5的25个格子(其中24个是字母,1个是空格),空格周围的字符都可以移动到空格处,首先输入这25个字符,然后再给你一连串移动命令,请你输出移动后格子中的字符情况。
难点
如果这25个字符没有空格的话,输入是很容易的,但偏偏是有空字符的,所以我们不能够使用cin或者scanf,因为他们都会跳过空字符。所以我们需要采用其他的方式,而其他方式恰恰是不经常练习的方式,这种情况下很容易出错。
坑点
- 命令字符串不是一次输完,可以多行输入,最后以0结尾,这道题是非getchar()输入不可了。
- 输出结果的最后一行末尾不能有空格,必须直接换行,UVA特色,这个点坑了我很多次了。
- 每个结果之间有空行,所以每次输出要换行两次,但是最后一行只能换行一次。
解决方案
这里推荐使用getchar()每次获取一个字符,然后根据字符进行不同的处理,需要注意的一点是每次读完一行字符后要多加一个getchar()来吞掉换行符;命令字符串同样用getchar输入直到检测到0;其他问题看代码理解。
代码
#include <bits/stdc++.h>
using namespace std;
char ma[8][8];
string s;
int x, y;
int change(int c) {
int xx = x, yy = y;
switch (c) {
case 'A': xx--;
break;
case 'B': xx++;
break;
case 'L': yy--;
break;
case 'R': yy++;
break;
}
if (xx < 1 || xx>5 || yy < 1 || yy>5)
return 0;
//调试
//cout << "字母" << ma[xx][yy] << "被换" << endl;
swap(ma[x][y], ma[xx][yy]);
x = xx, y = yy;
return 1;
}
void print() {
for (int i = 1; i <= 5; i++) {
for (int j = 1; j < 5; j++) {
cout << ma[i][j] << " ";
}
cout << ma[i][5] << endl;
}
}
void printErr() {
cout << "This puzzle has no final configuration." << endl;
}
int main()
{
#ifdef LOCAL
freopen("1.txt", "r", stdin);
#endif
int n = 1;
while (1) {
//初始化数组
memset(ma, '\0', sizeof(ma));
s.clear();
//输入数组
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
ma[i][j] = getchar();
if (ma[i][j] == 'Z')//读到Z结束
return 0;
if (ma[i][j] == ' ')
x = i, y = j; //找到空格
}
getchar();//去换行符
}
if (n > 1)cout << endl;
//输入命令
printf("Puzzle #%d:\n", n);
int k = 1;
int c;
while (c = getchar()) {
if (c == '\n')
continue;
if (c == '0')
break;
if (change(c) == 0)
k = 0;
}
getchar();
if (k == 1)
print();
else
printErr();
n++;
}
return 0;
}