1. 程式人生 > 其它 >【CF3C Tic-tac-toe】題解

【CF3C Tic-tac-toe】題解

題目連結

題目

Certainly, everyone is familiar with tic-tac-toe game. The rules are very simple indeed. Two players take turns marking the cells in a 3 × 3 grid (one player always draws crosses, the other — noughts). The player who succeeds first in placing three of his marks in a horizontal, vertical or diagonal line wins, and the game is finished. The player who draws crosses goes first. If the grid is filled, but neither Xs, nor 0s form the required line, a draw is announced.

You are given a 3 × 3 grid, each grid cell is empty, or occupied by a cross or a nought. You have to find the player (first or second), whose turn is next, or print one of the verdicts below:

  • illegal — if the given board layout can't appear during a valid game;
  • the first player won — if in the given board layout the first player has just won;
  • the second player won — if in the given board layout the second player has just won;
  • draw — if the given board layout has just let to a draw.

當然,大家都熟悉井字棋遊戲。 這些規則確實很簡單。 兩個玩家A、B輪流在3x3的方格的單元格中畫符號(玩家A總是畫“X”,玩家B總是畫“0”)。 首先在水平、垂直或對角線上出現3個相同的符號的玩家獲勝,比賽結束。 玩家A總是為先手。 如果3x3的方格被填滿,但是在所有水平、垂直或對角線上均未出現3個相同的符號,宣佈平局。

給你一個3*3的方格,每個單元格是“.”(空白),“X”或“0”。 你必須輸出以下內容之一:

玩家A走棋(輸出“first”)——如果出現給定的狀態後,下一步為玩家A走棋。

玩家B走棋(輸出“second”)——如果出現給定的狀態後,下一步為玩家B走棋。

非法(輸出“illegal”)——如果給定的狀態無法在正常遊戲過程中出現。

玩家A勝利(輸出“the first player won”)——如果給定的狀態中玩家A勝利。

玩家B勝利(輸出“the second player won”)——如果給定的狀態中玩家B勝利。

思路

一道語法題。

這道題難就不難,但很細節。

我的思路如此:

  1. 如果先手和後手棋子數不等或不是相差1,判無解。
  2. 接下來判斷先手與後手是否贏了。
  3. 如果先手贏,但後手還在下,無解。
  4. 如果後手贏,但先手還在下,無解。
  5. 如果棋盤被填滿,平局
  6. 如果先手數量大於後手,輪到後手
  7. 如果先手數量等於先手,輪到先手

考慮好這些題目就不難了。
平局(輸出“draw”)——如果給定的狀態是平局。

總結

對於此類題,明顯要考驗碼力的,在oi賽制中,要考慮清楚每一種情況,自己手動出幾組資料,同時更重要的是理解清題目。

做之前,最好先寫一寫優先順序。

Code


// Problem: CF3C Tic-tac-toe
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF3C
// Memory Limit: 62 MB
// Time Limit: 1000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include<bits/stdc++.h>
using namespace std;
//#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define M
//#define mo
//#define N
int n, m, i, j, k; 
char s[5][5]; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	scanf("%s%s%s", s[1]+1, s[2]+1, s[3]+1); 
	for(i=1; i<=3; ++i) for(j=1; j<=3; ++j) if(s[i][j]!='.')
		if(s[i][j]=='X') ++n; else ++m; 
	if(n-m!=0&&n-m!=1) return printf("illegal "), 0; 
	if(s[1][1]==s[1][2]&&s[1][2]==s[1][3]&&s[1][1]!='.')  s[1][1]=='X' ? i=1 : j=1; 
	if(s[2][1]==s[2][2]&&s[2][2]==s[2][3]&&s[2][1]!='.')  s[2][1]=='X' ? i=1 : j=1; 
	if(s[3][1]==s[3][2]&&s[3][2]==s[3][3]&&s[3][1]!='.')  s[3][1]=='X' ? i=1 : j=1; 
	if(s[1][1]==s[2][1]&&s[2][1]==s[3][1]&&s[1][1]!='.')  s[1][1]=='X' ? i=1 : j=1; 
	if(s[1][2]==s[2][2]&&s[2][2]==s[3][2]&&s[1][2]!='.')  s[1][2]=='X' ? i=1 : j=1; 
	if(s[1][3]==s[2][3]&&s[2][3]==s[3][3]&&s[1][3]!='.')  s[1][3]=='X' ? i=1 : j=1; 
	if(s[1][1]==s[2][2]&&s[2][2]==s[3][3]&&s[1][1]!='.')  s[1][1]=='X' ? i=1 : j=1; 
	if(s[1][3]==s[2][2]&&s[2][2]==s[3][1]&&s[1][3]!='.')  s[1][3]=='X' ? i=1 : j=1; 
	if(n>m&&j) return printf("illegal"), 0; 
	if(n==m&&i) return printf("illegal"), 0; 
	if(i|j) return printf("%s", i ? "the first player won" : "the second player won"), 0;
	if(n+m==9) return printf("draw"), 0; 
	printf("%s", n==m ? "first" : "second"); 
	return 0; 
}