POJ_1657:棋盤上的距離

1、問題描述:

Description

國際象棋的棋盤是黑白相間的8 * 8的方格,棋子放在格子中間。如下圖所示: 

王、後、車、象的走子規則如下: 
  • 王:橫、直、斜都可以走,但每步限走一格。 
  • 後:橫、直、斜都可以走,每步格數不受限制。 
  • 車:橫、豎均可以走,不能斜走,格數不限。 
  • 象:只能斜走,格數不限。


寫一個程序,給定起始位置和目標位置,計算王、後、車、象從起始位置走到目標位置所需的最少步數。 

Input

第一行是測試數據的組數t(0 <= t <= 20)。以下每行是一組測試數據,每組包括棋盤上的兩個位置,第一個是起始位置,第二個是目標位置。位置用"字母-數字"的形式表示,字母從"a"到"h",數字從"1"到"8"。 

Output

對輸入的每組測試數據,輸出王、後、車、象所需的最少步數。如果無法到達,就輸出"Inf".

Sample Input

2
a1 c3
f5 f8

Sample Output

2 1 2 1
3 1 1 Inf

二、解題思路自我理解:

①、本題的關鍵在於一個是理解清楚各中棋子的移動規則,第二個是恰當的表示起始位置和重點位置的表示,設起點和終點位置在水平方向上的距離是X,起點和終點在豎直方向上的距離是y。根據題目輸入輸出要求,用字符串數組儲存起點和終點位置,char begin[5]、 char end[5]分別儲存的是起點和終點的位置,顯然起點和終點在水平方向的距離x=abs(begin[0]-end[0]), 起點和終點在豎直方向的距離是y=abs(begin[1]-end[1]);

②、對於王來說,橫豎斜都可以走,但只能走一步,所以王的最少步子走法應該是先走一個等腰三角形的斜邊(等腰邊長是xy中兩者小者),然後直線走abs(x-y),對於在起點和終點的同一水平線或同一豎直線,可以理解爲等腰三角形的等腰邊爲0即可; (min(x,y) + abs(x-y) = max(x,y) )

③、對於後來說,由於每步格子不限,如果起點和終點在同一條水平線(y=0)或者在同一豎直線上(x=0)或在等腰三角形斜邊上(x=y),那麼一步到位,如果不是,那麼就是先一步走等腰三角形斜邊,第二步走xy差值;

④、對於車來說,不能斜走但橫豎步數不限,那麼要麼是一步(起點終點處於同一水平線或豎直線),要麼兩步(先橫後豎或者先豎後橫);

⑤、對於象來說,只能斜走,那麼存在不可達情況。斜走的一個重要特性是走的前後兩點其在棋盤上的橫縱座標差的奇偶性不會改變,意思是說只要兩點橫縱座標差同爲奇數或同爲偶數,就可達,否則不可達(Inf);對於可達情況的步數的確定,如果起點和終點在一個等腰三角形的上(橫座標差x = 縱座標差y),那麼就是一步。否則就是兩步。

⑥、由於在第⑤點中涉及到到了每個座標的橫縱差(abs(begain[0]-begain[1])、abs(end[0]-end[1])),前面只定義了起點終點座標的的相對橫縱差(x=abs(begin[0]-end[0])、y=abs(begin[1]-end[1])),一種比較低效的編碼方法是: 不可達情況即if( (abs(begin[0]-begin[1])%2==0&&abs(end[0]-end[1])%2!=0) ||(abs(begin[0]-begin[1])%2!=0&&abs(end[0]-end[1])%2==0)  printf("Inf\n"); 一種比較好的編碼方法是 if(abs(x-y)%2 !=0) printf("Inf\n"); ---- 兩點橫縱座標差同爲奇數或同爲偶數,根據同奇偶相減爲偶的原則即 abs【abs(begain[0]-begain[1]) - abs(end[0]-end[1])】爲偶數即可,【不理解前面的abs(x-y)就爲何等價於後面的abs嵌套,直接用後面的abs嵌套,直觀】。


三、源碼:

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int nCasses, i; //nCasses表示測試數據個數
	scanf("%d", &nCasses);
	for(i=0; i<nCasses; i++)
	{
		char begin[5], end[5];
		scanf("%s %s", begin, end);
		int x, y;
		x = abs(begin[0] - end[0]);
		y = abs(begin[1] - end[1]);
		if( x==0 && y==0) printf("0 0 0 0\n");
		else
		{
			if(x<y) printf("%d", y);
			else printf("%d", x); //王的步子情況,棋盤中等腰三角形斜邊和直邊的格子數是一樣的,min(x,y) + abs(x-y) = max(x,y)
			if(x==y || x==0 || y==0) printf(" 1");
			else printf(" 2");//後的步子情況
			if(x==0 || y==0) printf(" 1");
			else printf(" 2");//車的步子情況
			if(abs(x-y)%2 !=0) printf("Inf\n");
			else if(x==y) printf(" 1\n");
			else printf(" 2\n");//象的步子情況
		}
	}
	system("pasue");
	return 0;
}
			 
	

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章