题目来源:https://cn.vjudge.net/problem/UVA-227
题意:给定一个5*5的方格,有24个方块和一个空格组成(这里空格用#表示),例如:
TRGSJ
XDOKI
M#VLN
WPABE
UQHCF
同时给定一些操作(由一个字符确定):
A:表示空格上方的方块下移
B:表示空格下方的方块上移
L:表示空格左边的方块右移
R:表示空格右边的方块左移
经过一系列操作,输出最终方格状态,如果操作无效(比如该方向没有可移动的方块),直接输出一行提示结果。
题解:直接保存方格状态,模拟即可。读入状态后先查找空格所在位置,读入每个操作时,找到相应需要移动的方块,判断该位置是否有效:
(1)如果无效表明没有最终状态,将后续操作全部输入直到0为止。
(2)如果有效则将两个方格交换,并记录新的空格位置。
需要注意的是getline或者C语言的gets可能会读取到多余的换行符,需额外处理掉。
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 string mp[5]; 5 int posx, posy; 6 bool Check(int x, int y) 7 { 8 return x>=0&&x<5&&y>=0&&y<5; 9 } 10 11 void ReadAll() 12 { 13 char c; 14 while(cin>>c, c!='0'); 15 } 16 17 void Print() 18 { 19 for(int i=0;i<5;i++) 20 { 21 for(int j=0;j<5;j++) 22 { 23 if(j) 24 cout<<" "; 25 cout<<mp[i][j]; 26 } 27 cout<<endl; 28 } 29 } 30 31 void FindEmpty() 32 { 33 for(int i=0;i<5;i++) 34 { 35 for(int j=0;j<5;j++) 36 { 37 if(mp[i][j]==' ') 38 { 39 posx = i; 40 posy = j; 41 return; 42 } 43 } 44 } 45 } 46 47 int main() 48 { 49 //freopen("d:\data1.in","r",stdin); 50 int cas = 1; 51 while(getline(cin, mp[0]), mp[0]!="Z") 52 { 53 for(int i=1;i<5;i++) 54 { 55 getline(cin, mp[i]); 56 } 57 FindEmpty(); 58 char c; 59 int flag = 0; 60 while(cin>>c, c!='0') 61 { 62 int x, y; 63 if(c=='A') 64 { 65 x = posx - 1; 66 y = posy; 67 } 68 else if(c=='B') 69 { 70 x = posx + 1; 71 y = posy; 72 } 73 else if(c=='L') 74 { 75 x = posx; 76 y = posy -1; 77 } 78 else if(c=='R') 79 { 80 x = posx; 81 y = posy + 1; 82 } 83 if(!Check(x, y)) 84 { 85 flag = 1; 86 ReadAll(); 87 break; 88 } 89 swap(mp[x][y], mp[posx][posy]); 90 posx = x; 91 posy = y; 92 } 93 if(cas!=1) 94 cout<<endl; 95 cout<<"Puzzle #"<<cas<<":"<<endl; 96 cas++; 97 if(flag==1) 98 { 99 cout<<"This puzzle has no final configuration."<<endl; 100 } 101 else 102 { 103 Print(); 104 } 105 getchar(); 106 } 107 return 0; 108 }