题目大意:
给出5*5的格子,其中有一个空格子,然后有一些命令。ABLR分别对应的上下左右,每一次移动两个格子都交换位置,命令以0结束。如果有非法操作则直接给出提示。
解题思路:
一道很好的模拟题,对于每个移动判一下是不是非法操作,不是非法操作的话模拟交换两个格子即可,代码很好理解,但是有很多坑点。
- 在输入的过程中,如果这一行最后一个格子是空格的话他是不会输入的,而是直接换行!!!
- 命令可能有多行,会有换行符,但一定是以0结束的。
- 输入输出!!调了一上午,输入我这边直接都用的getline(),cin是不吃空格的。而且getline也能很好的保证最后一个格子是换行符的情况。输出的话第一行和最后一行是没有换行的,这个地方PE了近10次。
感想:
不愧是WF。。坑点太多,质量很高的模拟题,但是输入输出还需要多加练习…调了一上午才调好。。UVA格式太坑
AC代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <sstream>
#include <map>
using namespace std;
string mp[6];
int main()
{
int k=1;
while(true)
{
int x,y;
for(int i=0;i<5;i++)
{
getline(cin,mp[i]);
if(mp[i].length()==4)//针对最后一列是0的情况
mp[i][4]=' ';
if(mp[0][0]=='Z')//Z是退出程序
return 0;
}
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
if(mp[i][j]==' ')//记录一下空格的位置方便后面判非法
x=i,y=j;
string s="",s1;
while(true)
{
getline(cin,s1);
s+=s1;//把所有命令整合到一起
if(s1[s1.length()-1]=='0')//如果没遇到0则一直输入命令
break;
}
bool flag=true;
for(int i=0;i<s.length()-1;i++)
{
if(s[i]=='A')//枚举4个方向 先判非法,再模拟移动
{
if(x==0)
{
flag=false;
break;
}
swap(mp[x][y],mp[x-1][y]);
x--;//注意空格的位置要变
}
if(s[i]=='B')
{
if(x==4)
{
flag=false;
break;
}
swap(mp[x][y],mp[x+1][y]);
x++;
}
if(s[i]=='L')
{
if(y==0)
{
flag=false;
break;
}
swap(mp[x][y],mp[x][y-1]);
y--;
}
if(s[i]=='R')
{
if(y==4)
{
flag=false;
break;
}
swap(mp[x][y],mp[x][y+1]);
y++;
}
}
if(k>1)//输出格式一定一定注意,第一个样例和最后一个样例无换行
cout<<endl;
printf("Puzzle #%d:
",k++);
if(!flag)//非法
{
cout<<"This puzzle has no final configuration."<<endl;
continue;
}
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
if(j!=4)
cout<<mp[i][j]<<" ";
else
cout<<mp[i][j];
cout<<endl;
}
}
return 0;
}