问题链接:UVA227 Puzzle。基础训练级的问题,用C语言编写程序。
问题简述:一个5×5的网格,一个格子是空的,其他格子各有一个字母,一共有四种指令:A,B,L,R,分别表示把空格上、下、左、右的相邻字母移到空格中。输入初始网格和指令序列,指令序列以数字0结束,输出指令执行完毕后的网格。如果有非法指令,应输出"This puzzle has no final configuration."。
这个题的问题可能会出在输入处理上。根据实例,输入的指令序列可能是多行的,需要小心处理。
另外一点,当模拟出错时,需要正确处理。模拟出错的情况有两种,一是输入指令错误;二是输入指令虽然正确,而把空格移动到网格外面的情况。
程序中,封装了函数move()用于接受指令,模拟根据指令空格的移动过程。主程序则用于处理输入、输出和整体控制。
AC的C语言程序如下:
/* UVA227 Puzzle */ #include <stdio.h> #define MAXN 5 char grid[MAXN][MAXN]; int blankrow, blankcol, nextrow, nextcol; // 移动:如果指令正确则移动,并且返回0;否则返回1。 int move(char move) { if(move == 'A') { nextrow = blankrow - 1; nextcol = blankcol; } else if(move == 'B') { nextrow = blankrow + 1; nextcol = blankcol; } else if(move == 'L') { nextrow = blankrow; nextcol = blankcol - 1; } else if(move == 'R') { nextrow = blankrow; nextcol = blankcol + 1; } else return 1; if(nextrow >= 0 && nextrow < MAXN && nextcol >= 0 && nextcol < MAXN) { grid[blankrow][blankcol] = grid[nextrow][nextcol]; grid[nextrow][nextcol] = ' '; blankrow = nextrow; blankcol = nextcol; return 0; } else return 1; } int main(void) { int caseno=0, okflag, i, j; char c; while((c=getchar()) != 'Z') { // 读入数据 for(i=0; i<MAXN; i++) for(j=0; j<MAXN; j++) { grid[i][j] = c; if(c == ' ' || c == ' ') { blankrow = i; blankcol = j; grid[i][j] = ' '; } c = getchar(); if(j == MAXN-1 && c == ' ') c = getchar(); } // 模拟过程:一边读入命令行,一边移动 okflag = 1; while(c != '0') { if(c != ' ') { if(move(c)){ okflag = 0; break; } } c = getchar(); if(c == ' ') c = getchar(); } while(c != '0') // 跳过‘0’及以前的字符 c = getchar(); while(c != ' ') // 跳过‘ ’及以前的字符 c = getchar(); // 输出结果 if(++caseno > 1) printf(" "); printf("Puzzle #%d: ", caseno); if(okflag) { for(i=0; i<MAXN; i++) printf("%c %c %c %c %c ", grid[i][0], grid[i][1], grid[i][2], grid[i][3], grid[i][4]); } else printf("This puzzle has no final configuration. "); } return 0; }