题目大意:
有一个5*5的方阵,其中有一个空格,可以把上下左右的字母移过去。一共有四种操作,ABLR——上下左右,0表示操作结束。多组输入,输入Z结束。先给出初始方阵(注意如果直接拷贝样例数据,末尾的空格是不存在的),再给出一个操作字符串(注意可能不在一行),要求输出变换后的方阵(注意Puzzle前有一个空行),如果有非法操作(方阵移动越界等),就输出“This puzzle has no final configuration.”。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
char a[5][5];
int kase = 1;
char ch;
while(cin.getline(a[0],6) && a[0][0]!='Z')
{
for(int i=1; i<5; i++)
{
cin.getline(a[i],6);
}
string act = "";
while((ch = getchar()) != '0')
{
if(ch != '\n')
act += ch;
}
int n = act.length();
int flag = 1; //是否有非法指令
int posi=0, posj=0;
for(int i=0; i<5; i++)
{
for(int j=0; j<5; j++)
{
if(a[i][j] == ' ')
{
posi = i;
posj = j;
}
}
}
for(int i=0; i<n; i++)
{
if(act[i] == 'A')
{
if(posi-1 >= 0)
{
a[posi][posj] = a[posi-1][posj];
a[posi-1][posj] = ' ';
posi--;
}
else
{
flag = 0;
break;
}
}
else if(act[i] == 'B')
{
if(posi+1 < 5)
{
a[posi][posj] = a[posi+1][posj];
a[posi+1][posj] = ' ';
posi++;
}
else
{
flag = 0;
break;
}
}
else if(act[i] == 'L')
{
if(posj-1 >= 0)
{
a[posi][posj] = a[posi][posj-1];
a[posi][posj-1] = ' ';
posj--;
}
else
{
flag = 0;
break;
}
}
else if(act[i] == 'R')
{
if(posj+1 < 5)
{
a[posi][posj] = a[posi][posj+1];
a[posi][posj+1] = ' ';
posj++;
}
else
{
flag = 0;
break;
}
}
else if(act[i] == '\0')
{
break;
}
else
{
flag = 0;
}
}
if(kase != 1)
cout << endl;
cout << "Puzzle #" << kase++ << ":" << endl;
if(flag)
{
for(int i=0; i<5; i++)
{
for(int j=0; j<5; j++)
{
cout << a[i][j];
if(j != 4) cout << " ";
}
cout << endl;
}
}
else
{
cout << "This puzzle has no final configuration." << endl;
}
getchar();
}
return 0;
}
反思:
格式比较严格的一个字符串练习题。坑点是Puzzle前的空行……无限PE。代码还是过于繁琐了,其实可以用一个dir[]数组保存四个方向,直接进行加操作,找空格可以在存储方阵时一并完成。