演算法的樂趣c/c++ —— 1.1.9入門習題
阿新 • • 發佈:2018-12-26
宣告:摘選自“ 演算法競賽入門經典(第2版)”作者: 劉汝佳 / 陳鋒 ISBN:9787302291077
謎題
有一個5 * 5的網格,其中恰好有一個格子是空的,其他格子各有一個字母。一共有4種指令:A,B,L,R,分別表示把空格上,下,左,右的相鄰字母移到空格中。輸入初始網格和指令序列(以數字0結束),輸出指令執行完畢後的網格。如果有非法指令,應輸出“這個拼圖沒有最終的配置。”,例如,圖左中執行ARRBBL0後,效果如圖右所示。
解題思路
其實只要利用的getchar()迴圈讀入字元,然後將其按照5×5的格式存放在二維字元陣列,然後記錄空格的位置,再根據就輸入的命令將空格與對應的字元交換值即可:
#include<stdio.h> #include<string.h> char s[6][6]; //定義一個儲存字母的二維字串陣列 int main() { char c, comd; //c用於存放讀取的字元,comd用於存放讀取的命令字元 int i=0, j=0, x, y; //i,j用於記錄網格的座標,x,y用於記錄空格的座標 while((c = getchar()) !='0') //迴圈讀取字元 ,當輸入‘0’時停止迴圈 { if(c != '0') s[i][j] = c; //因為停止命令是‘0’,我們必須判斷是否將‘0’讀入了,如果讀入,則不會將其放入陣列s[][] if(c == ' ') //如果讀入的是空格,用x,y記錄其座標 { x = i; y =j ; } j ++; //s[i][j]向右移動一位進行記錄 if(j==5) //當s[i][j]第一行儲存滿了之後,向下移動一位 { i ++; j = 0; } } for(int m=0; m<5; m++) //將讀入的字元按照5*5格式列印 { for(int n=0; n<5; n++) { printf("%c ", s[m][n]); if(n==4) printf("\n"); } } while((comd=getchar()) != '0') //迴圈讀入命令字元,遇到‘0’停止讀取,結束迴圈 { if(comd == 'A') //向上移動空格 { s[x][y] = s[x-1][y]; s[x-1][y] = ' '; x = x-1; } else if(comd == 'B') //向下移動空格 { s[x][y] = s[x+1][y]; s[x+1][y] = ' '; x = x+1; } else if(comd == 'R') //向右移動空格 { s[x][y] = s[x][y+1]; s[x][y+1] = ' '; y = y+1; } else if(comd == 'L') //向左移動空格 { s[x][y] = s[x][y-1]; s[x][y-1] = ' '; y = y-1; } else //輸入非法字元時輸出 { printf("This puzzle has no final configuration."); return 0; } } printf("\n"); //換行,以便分辨原始陣列與處理後的陣列 for(int m=0; m<5; m++) //將處理後的字元按照5*5格式列印 { for(int n=0; n<5; n++) { printf("%c ", s[m][n]); if(n==4) printf("\n"); } } }
效果圖如下: