謎題(Puzzle, ACM/ICPC World Finals 1993, UVa227)(難死了!!)
阿新 • • 發佈:2019-02-12
有一個5*5的網格,其中恰好有一個格子是空的,其他格子各有一個字母。一共有4種指令:A, B, L, R,分別表示把空格上、下、左、右的相鄰字母移到空格中。輸入初始網格和指令序列(以數字0結束),輸出指令執行完畢後的網格。如果有非法指令,應輸出“This puzzle has no final configuration.”
例如,圖3-5中執行ARRBBL0後,效果如圖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)是否終止程式。
2)讀入資料是否為第一行。
3)a[0]為第一行,a[0][0]為第一行的第一個字母,gets(a[0])讀入了第一行!之後要從第二行讀。
4)注意空格位置的判斷和讀入!! - 移動:
1)是否為0終止移動
2)s[i],dir[][]的巧法
3)空位置的更改、記錄 - 輸出:
1)根據移動是否正確輸出
2)為空時的輸出