黑白棋

黑白棋是一種羣衆喜聞樂見的棋類遊戲,雙方各執黑白一色棋子,在 8 * 8 的棋盤上進行比賽(棋盤初始佈局如下圖),雙方輪流下子,黑棋先手。

每次行動,玩家可以選擇在棋盤中任意的有效格子處下子。在落子後,會進行八個方向的翻轉操作。

翻轉操作的過程是這樣的:以剛放下的那顆棋子爲中心(簡稱爲中心棋子),在上、下、左、右、左上、左下、右上、右下八個射線方向內,分別尋找一個離中心棋子最近的己方顏色的棋子(簡稱爲外側棋子)。如果某個方向不存在外側棋子,或者中心棋子和外側棋子之間存在空白格子,或者中心棋子和外側棋子直接相鄰,則該方向是無效的,需要跳過。

如果一個翻轉方向是有效的,則對其執行翻轉操作,將中心棋子和外側棋子之間的所有棋子都變成己方顏色的棋子。

而所謂的有效格子,則表示該格子是一個空白格子,並且在該格子處下子,至少有一個方向能出現有效翻轉。

由於 Dr. Cat 和 Prof. Chi 的腦補水平已經達到正常人的 6 倍,他們下棋完全不需要棋盤,僅僅用語言就能在腦中進行對決。而作爲一般人的 Kotomi,根本搞不清他們的 N 步操作之後會變成什麼樣的局面。所以 Kotomi 請求你,勇敢的少年,快用你的程序創造奇蹟吧!


輸入格式

一個整數 T,表示有多少組測試數據。

對於每組測試數據,第一行是一個整數 N (1 <= N <= 60),表示這局黑白棋當前已經下過了 N 步棋子。

接下來的 N 行,每一行給出一個數字 X (1 <= X <= 8) 和一個字符 Y ('A' <= Y <= 'H'),表示棋子落在的位置。這些棋子是按照從開局到結束的行動順序依次給出的,數據保證所有操作都是合法操作,並且不存在某個人無法落子的情況。

輸出格式

對於每組測試數據,輸出最終的棋盤局面。黑子由 ‘#’ 表示,白子由 ‘*’ 表示,空白的格子由 ‘.’ 表示。棋盤的格子之間由一個空格隔開,棋盤的行號和列號也要輸出。具體細節請參照樣例,注意不要有多餘的空白和換行符。

樣例輸入

2
2
5 F
4 F
6
5 F
4 F
3 E
6 F
5 G
3 F

樣例輸出

  A B C D E F G H
1 . . . . . . . .
2 . . . . . . . .
3 . . . . . . . .
4 . . . * * * . .
5 . . . # # # . .
6 . . . . . . . .
7 . . . . . . . .
8 . . . . . . . .
  A B C D E F G H
1 . . . . . . . .
2 . . . . . . . .
3 . . . . # * . .
4 . . . * # * . .
5 . . . # # * # .
6 . . . . . * . .
7 . . . . . . . .
8 . . . . . . . .

本人代碼:

#include<stdio.h>
#include<string.h>

int a[9][9];
int xis[]={-1,  1,  0,  0,  -1, -1,  1,   1};  //上,下,左,右,左上,坐下,右上,右下
int yis[]={ 0,  0, -1,  1,  -1,  1,  -1,  1};
void print()
{
	int i,j;
	printf(" ");
	for(i=0;i<8;i++)
		printf(" %c",'A'+i);
	printf("\n");
	for(i=1;i<=8;i++)
	{
		printf("%d",i);
		for(j=1;j<=8;j++)
			if(a[i][j]==1)
				printf(" #");
			else if(a[i][j]==-1)
				printf(" *");
			else
				printf(" .");
		printf("\n");
	}
		
}

//每走一步,執行的變換
void translate(int X,int Y, bool black)
{
	int flag; //用於標記,當前是黑棋還是白棋
	if(black)
		flag=1;
	else
		flag=-1;
	
	a[X][Y]=flag;
	//printf("a[%d][%d]:%d\n",X,Y,a[X][Y]);
	int i,xi,yi,tempX,tempY;
	for(i=0;i<8;i++) //遍歷8個方向
	{  
		xi=xis[i];
		yi=yis[i];
		//printf("%d:%d方向搜索\n",xi,yi);
		tempX=X+xi;
		tempY=Y+yi;
		int count=0;  //用於計數,在xi,yi方向上走的步數
		while(tempX>=1 && tempY>=1 && a[tempX][tempY]==-flag) 
		{ //xi,yi方向上搜索;如果是和X,Y上棋子顏色相反的,就繼續搜索
			count++;
			tempX+=xi;
			tempY+=yi;
		}
		//停止搜索時,如果遇到的是和X,Y上相同的棋子,就將(tempX,tempY)和(X,Y)之間的棋子,置爲(X,Y)上的棋子
		if(tempX>=1 && tempY>=1 && a[tempX][tempY]==flag )
		{  //printf("%d:%d上有%d個變換\n",xi,yi,count);
			tempX-=xi;
			tempY-=yi;
			//循環條件用count,不能用註釋中的,tempX,tempY是八個方向的,搜索停止時,不一定都滿足(tempX<=X && tempY<=Y)
			while(count--)//while(tempX<=X && tempY<=Y), 
			{
				a[tempX][tempY]=flag;
				tempX-=xi;
			    tempY-=yi;
			}
		}
	}
}

void getOneTest()
{
	int N; //走的步數
	int X; //每一步走的棋子,
	char Y;
	memset(a,0,sizeof(a)); //初始化爲0,黑棋1,白棋-1
	a[4][4]=-1;
	a[4][5]=1;
	a[5][4]=1;
	a[5][5]=-1;
	
	scanf("%d",&N);
	bool black=true;
	while(N--)
	{
		scanf("%d %c",&X,&Y);
		Y=Y-'A'+1; //轉換成座標, 座標從1開始,和棋盤對應
		
		translate(X,Y,black);
		black=!black;
	}
	print();
}
int main()
{  
	int T;
	scanf("%d",&T);
	while(T--)
		getOneTest();
}


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