1. 程式人生 > >演算法的樂趣c/c++ —— 1.1.9入門習題

演算法的樂趣c/c++ —— 1.1.9入門習題

宣告:摘選自“   演算法競賽入門經典(第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");
		}
	}	

} 

效果圖如下: