1. 程式人生 > >謎題(Puzzle, ACM/ICPC World Finals 1993, UVa227)(難死了!!)

謎題(Puzzle, ACM/ICPC World Finals 1993, UVa227)(難死了!!)

有一個5*5的網格,其中恰好有一個格子是空的,其他格子各有一個字母。一共有4種指令:A, B, L, R,分別表示把空格上、下、左、右的相鄰字母移到空格中。輸入初始網格和指令序列(以數字0結束),輸出指令執行完畢後的網格。如果有非法指令,應輸出“This puzzle has no final configuration.”

例如,圖3-5中執行ARRBBL0後,效果如圖3-6所示。

圖3-6

輸入:
TRGSJ
XDOKI
M__VLN
WPABE
UQHCF
ARRBBL0
ABCDE
FGHIJ
KLMNO
PQRS__
TUVWX
AAA
LLLL0
ABCDE
FGHIJ
KLMNO
PQRS__
TUVWX
AAAAABBRRRLL0
Z

輸出:
Puzzle #1:
T R G S J
X O K L I
M D V B N
W P _ A E
U Q H C F

Puzzle #2:
_ A B C D
F G H I E
K L M N J
P Q R S O
T U V W X

Puzzle #3:
This puzzle has no final configuration.

程式碼(wuliRUI):

#include<stdio.h>
#include<string.h>
#include <cctype>
#define maxn 5

const
int dir[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}}; const char s[] = "ABRL"; char a[maxn][maxn]; int main() { int t = 0; while(gets(a[0])) {//注意讀的是第一行! //讀入 if(a[0][0] == 'Z') break;//判斷的是第一個字母 if (t) { puts(""); } int m = 0, n = 0; for(int i = 0; i <= 4
; ++i) { if (i) {//不是第一行 gets(a[i]); } for(int j = 0; j <= 4; ++j) { if(a[i][j] == ' ' || a[i][j] == 0) {//注意 前四個位置是否有空,或第五個位置(字串尾)為空不顯示!且若||前面的成立不讀後面的! a[i][j] = ' '; m = i; n = j;//將空的位置記下來 } } } //移動 bool ok = true; for (;;) { char c = getchar(); if (c == '0') { break; } bool q = isspace(c);//isspace(c):檢查引數c是否為空白字元,是為真,否為假 for (int i = 0; i < 4 && ok; ++i) { if (c == s[i]) {//c為R,L,A,B中的一個 q = true; int x = m + dir[i][0], y = n + dir[i][1];//將新的位置算出(方法巧不用寫那麼多) if (x < 0 || x > 4 || y < 0 || y > 4) { ok = false; break; } a[m][n] = a[x][y];//將移動位置上的字母給空的位置 a[x][y] = ' ';//將新位置為空 m = x, n = y;//重新記新的位置 } } if (!q) {// q 是為了判斷是否是空白字元的時候 ok = false; } } //輸出 printf("Puzzle #%d:\n", ++t); if (ok) { for(int i = 0; i <= 4; ++i) { for(int j = 0; j <= 4; ++j) { if (j) { printf(" ");//輸空格用的,最後字母后沒空格 } printf("%c", a[i][j]); } printf("\n"); } } else { printf("This puzzle has no final configuration.\n"); } } return 0; }

執行:
這裡寫圖片描述

注意:

  1. 讀入:
    1)是否終止程式。
    2)讀入資料是否為第一行。
    3)a[0]為第一行,a[0][0]為第一行的第一個字母,gets(a[0])讀入了第一行!之後要從第二行讀。
    4)注意空格位置的判斷和讀入!!
  2. 移動:
    1)是否為0終止移動
    2)s[i],dir[][]的巧法
    3)空位置的更改、記錄
  3. 輸出:
    1)根據移動是否正確輸出
    2)為空時的輸出