《算法竞赛入门经典(第2版)》 习题3-5 谜题 (Puzzle, ACM/ICPC World Finals 1993, UVa227)
有一个5*5的网格,其中恰好有一个格子是空的,其他格子各有一个字母。一共有4种指令:A,B,L,R,分别表示把空格上、下、左、右的相邻字母移到空格中。输入初始网格和指令序列(以数字0结束),例如ARRBBL0,输出指令执行完毕后的网格。如果有非法指令,应输出“This puzzle has no final configuration.”。
分析
此题是典型的模拟题(即“按照题目说的做”),只要按照题目描述的过程输入数据、输入指令序列,然后按照每个指令移动网格,遇到0时停止,最后输出执行后的网格即可。
代码
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
char a[7][7] = {0}, c;
char op[1000];
int main()
{
int i = 1, j = 1, tot=0, x, y; // (x,y)是空格的位置
while((c=getchar())!=EOF && tot<25) // 输入5*5的网络数据
{
if((c>='A' && c<='Z') || c==' '){
a[i][j] = c;
if(c==' ') {x=i;y=j;} // 记录空格的位置
tot++;
j++;
if(j>5) j=j%5;
}
else if(c=='\n') i++;
}
scanf("%s", op); // 输入指令序列
for(i=0; i<strlen(op); i++)
{
if(op[i]=='0') break; // 0结束
else if(op[i]=='A'){ // 与上方字母交换
if(a[x-1][y]!=0){a[x][y] = a[x-1][y]; a[x-1][y] = ' ';x = x-1;} // 可以交换,更新位置
else printf("This puzzle has no final configuration.\n"); // 非法操作,不能交换
}
else if(op[i]=='B'){ // 与下方字母交换
if(a[x+1][y]!=0){a[x][y] = a[x+1][y]; a[x+1][y] = ' ';x = x+1;} // 可以交换,更新位置
else printf("This puzzle has no final configuration.\n"); // 非法操作,不能交换
}
else if(op[i]=='L'){ // 与左方字母交换
if(a[x][y-1]!=0){a[x][y] = a[x][y-1]; a[x][y-1] = ' ';y = y-1;} // 可以交换,更新位置
else printf("This puzzle has no final configuration.\n"); // 非法操作,不能交换
}
else if(op[i]=='R'){ // 与右方字母交换
if(a[x][y+1]!=0){a[x][y] = a[x][y+1]; a[x][y+1] = ' ';y = y+1;} // 可以交换,更新位置
else printf("This puzzle has no final configuration.\n"); // 非法操作,不能交换
}
}
for(i=1; i<=5; i++)
{
for(j=1; j<=5; j++)
printf("%c", a[i][j]);
printf("\n");
}
return 0;
}