2018.1.21【CodeForces - 825B】解題報告(模擬,五子棋)

B. Five-In-a-Row
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Alice and Bob play 5-in-a-row game. They have a playing field of size 10 × 10. In turns they put either crosses or noughts, one at a time. Alice puts crosses and Bob puts noughts.

In current match they have made some turns and now it's Alice's turn. She wonders if she can put cross in such empty cell that she wins immediately.

Alice wins if some crosses in the field form line of length not smaller than 5. This line can be horizontal, vertical and diagonal.

Input

You are given matrix 10 × 10 (10 lines of 10 characters each) with capital Latin letters 'X' being a cross, letters 'O' being a nought and '.' being an empty cell. The number of 'X' cells is equal to the number of 'O' cells and there is at least one of each type. There is at least one empty cell.

It is guaranteed that in the current arrangement nobody has still won.

Output

Print 'YES' if it's possible for Alice to win in one turn by putting cross in some empty cell. Otherwise print 'NO'.

Examples
input
XX.XX.....
.....OOOO.
..........
..........
..........
..........
..........
..........
..........
..........
output
YES
input
XXOXX.....
OO.O......
..........
..........
..........
..........
..........
..........
..........
..........
output
NO


【題目大意】

給定一個五子棋棋盤,判斷X棋一步之後能否勝利。

【解題思路】

沒什麼,自己寫模擬。遍歷每個可下的點判斷橫豎和斜方向上能否實現大於等於五子相連。

注意邊界問題,可以採用左右上下各拓展4行4列。

【解題代碼】

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#define maxn 10010
using namespace std;
char map[20][20];
bool check(int a,int b)
{
	map[a][b]=1;
//	printf("begin check %d %d\n",a,b);
		int conti,i,j;
		for(conti=0,i=a-4;i<=a+4;i++) //橫向判斷 
		{
			if(map[i][b]==1) 
			{
				conti++;
				if(conti>4) return true;
			}
			else
			{
				conti=0;
				continue;
			}
		} 
		for(conti=0,j=b-4;j<=b+4;j++) //縱向判斷 
		{
			if(map[a][j]==1) 
			{
				conti++;
				if(conti>4) return true;
			}
			else
			{
				conti=0;
				continue;
			}
		} 
		for(conti=0,i=a-4,j=b-4;i<=a+4;i++,j++) //斜向判斷1 
		{
			if(map[i][j]==1)
			{
				conti++;
				if(conti>4) return true;
			}
			else 
			{
				conti=0;
				continue;
			}
		}
		
		for(conti=0,i=a-4,j=b+4;i<=a+4;i++,j--) //斜向判斷1 
		{
			if(map[i][j]==1)
			{
				conti++;
				if(conti>4) return true;
			}
			else 
			{
				conti=0;
				continue;
			}
		}
		map[a][b]=0;
		return false; 
}
int main()
{
//	freopen("in.txt", "r", stdin);//其實in.txt是可以修改成其他名字的  比如“輸入.txt”,都是可以的,這裏只是爲了方便起見,下同; 
	for(int i=0+4;i<10+4;i++)
	{
		scanf("%s",map[i]+4);	
	}
	for(int i=0+4;i<10+4;i++)
	{
		for(int j=0+4;j<10+4;j++)
		{
			switch(map[i][j])	
			{
				case 'X': map[i][j]=1;break;
				case 'O': map[i][j]=2;break;
				case '.': map[i][j]=0;break;
			}
//			printf("%d ",map[i][j]);
		}
//		printf("\n");
	}
	int flag=0;
	for(int i=0+4;i<10+4;i++)
	{
		for(int j=0+4;j<10+4;j++)
		{
			if(map[i][j]||!map[i-1][j]&&!map[i+1][j]&&!map[i][j-1]&&!map[i][j+1]&&!map[i-1][j-1]&&!map[i+1][j+1]&&!map[i-1][j+1]&&!map[i+1][j-1]) continue;
			else flag=check(i,j);
			if(flag)
			{
//				printf("%d %d \n",i-4,j-4);
				break;
			}
		}
		if(flag)
			break;
	}
	if(flag)
		printf("YES\n");
	else printf("NO\n");
//	fclose(stdin);
//	fclose(stdout);
	return 0;
}

【總結與反思】

模擬的時候要注意細節,儘量不要返工。

既然是遍歷,能簡化的簡化,比如判定周圍一圈沒有棋子可以直接continue跳過該循環。

發佈了40 篇原創文章 · 獲贊 1 · 訪問量 6269
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章