UPC-自习课 模拟题
题目描述
自习课就是划水课。
你和同桌在玩井字棋,你先手。突然老师进来了。
给定一个局面,问它是否有可能下的出来。
若有可能,求出是否有赢家,若有,输出赢家。
否则,输出是否平局,或者下一步是谁的回合。
输入
有多组数据,第一行给出数据组数 T。
每组数据有 3 行,每行 3 个字符。
若字符为”X”,表示这里你下过,若字符为”O”,表示这里同桌下过。
若字符为”.”,表示这里没有人下过。
输出
每个数据输出一行。
若不可能下的出来,输出Illegal Situation。
若你赢了,输出X wins,若同桌赢了,输出O wins。
若已经下完了,且平局,输出Draw。
若下一步是你的回合,输出X’s turn。
若下一步是同桌的回合,输出O’s turn。
样例输入 Copy
5
...
XX.
..O
XOX
XXO
OXO
.O.
XO.
.O.
XOX
OX.
X.O
XXX
OOO
...
样例输出 Copy
O's turn
Draw
Illegal Situation
X wins
Illegal Situation
提示
对于前 60% 的数据,不存在三个”X”或”O”连成一线的情况;
对于 100% 的数据,T≤100。
仅以这篇博客纪念一下自己的失误ss [ 1 ] [ 3 ] 打成了ss [ 3 ] [ 1 ]
相信这个游戏大家都玩过,模拟就行了;
特殊的判断如下:
X和O的数量之间的差不能超过两个,并且先手X的数量一定要大于等于O的数量,并且两人不能同时取得游戏的胜利 这是判断不合法的情况
开局的时候X先下,X和O二者棋子数量相等的情况下,X下
棋盘上都下满并且X数量是5,O数量是4并且二人都没有赢得比赛的时候,此时为平局
X和O赢得比赛的时候的情形比较好判断,这里不再赘述
两人都没有赢得比赛并且数量相等的情况下,X走,反之要是X大一个,那么O走,对于已经下满的情况在上面已经过滤掉不用担心
判断是否赢得比赛的情况比较鲁莽,没有用到循环,手动尴尬
Code:
#include <bits/stdc++.h>
using namespace std;
#define wuyt main
typedef long long ll;
#define HEAP(...) priority_queue<__VA_ARGS__ >
#define heap(...) priority_queue<__VA_ARGS__,vector<__VA_ARGS__ >,greater<__VA_ARGS__ > >
template<class T> inline T min(T &x,const T &y){return x>y?y:x;}
template<class T> inline T max(T &x,const T &y){return x<y?y:x;}
///#define getchar()(p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
///char buf[(1 << 21) + 1], *p1 = buf, *p2 = buf;
ll read(){ll c = getchar(),Nig = 1,x = 0;while(!isdigit(c) && c!='-')c = getchar();
if(c == '-')Nig = -1,c = getchar();
while(isdigit(c))x = ((x<<1) + (x<<3)) + (c^'0'),c = getchar();
return Nig*x;}
#define read read()
const ll inf = 1e15;
const ll INF = 0x3f3f3f3f;
const int maxn = 2e6 + 7;
const int mod = 998244353;
#define start int wuyt()
#define end return 0
#define pi 3.14159265358979323846
ll maxx=-1;
ll minn=inf;
ll num[maxn];
int ct;
///ll a[maxn];
ll num2[maxn];
ll res,ans;
priority_queue <int ,vector<int> ,greater<int> > xiaogen;
priority_queue <int ,vector<int> ,less<int> > dagen;
char ss[5][5];
bool x_win(){
if(ss[1][1]=='X'&&ss[1][2]=='X'&&ss[1][3]=='X') return true;
if(ss[2][1]=='X'&&ss[2][2]=='X'&&ss[2][3]=='X') return true;
if(ss[3][1]=='X'&&ss[3][2]=='X'&&ss[3][3]=='X') return true;
if(ss[1][1]=='X'&&ss[2][1]=='X'&&ss[3][1]=='X') return true;
if(ss[1][2]=='X'&&ss[2][2]=='X'&&ss[3][2]=='X') return true;
if(ss[1][3]=='X'&&ss[2][3]=='X'&&ss[3][3]=='X') return true;
if(ss[1][1]=='X'&&ss[2][2]=='X'&&ss[3][3]=='X') return true;
if(ss[3][1]=='X'&&ss[2][2]=='X'&&ss[1][3]=='X') return true;
return false;
}
bool o_win(){
if(ss[1][1]=='O'&&ss[1][2]=='O'&&ss[1][3]=='O') return true;
if(ss[2][1]=='O'&&ss[2][2]=='O'&&ss[2][3]=='O') return true;
if(ss[3][1]=='O'&&ss[3][2]=='O'&&ss[3][3]=='O') return true;
if(ss[1][1]=='O'&&ss[2][1]=='O'&&ss[3][1]=='O') return true;
if(ss[1][2]=='O'&&ss[2][2]=='O'&&ss[3][2]=='O') return true;
if(ss[1][3]=='O'&&ss[2][3]=='O'&&ss[3][3]=='O') return true;
if(ss[1][1]=='O'&&ss[2][2]=='O'&&ss[3][3]=='O') return true;
if(ss[3][1]=='O'&&ss[2][2]=='O'&&ss[1][3]=='O') return true;
return false;
}
int main()
{
int n=read;
while(n--){
int cntx=0,cnto=0;
for(int i=1;i<=3;i++)
cin>>ss[i]+1;
/// 统计数量
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
if(ss[i][j]=='X') cntx++;
else if(ss[i][j]=='O') cnto++;
}
}
///差值>=2 不合法 数量上
if(abs(cntx-cnto)>=2||cnto>cntx||o_win()&&x_win()){
printf("Illegal Situation\n");
continue;
}
else {
if(cntx==cnto&&cntx==0) {
printf("X's turn\n");
continue;
}
if(cntx==5&&cnto==4&&!o_win()&&!x_win()){
printf("Draw\n");///平局ok
continue;
}
if(o_win()&&!x_win()&&cntx==cnto){
printf("O wins\n");
continue;
}
if(!o_win()&&x_win()&&cntx==cnto+1){
printf("X wins\n");
continue;
}
if(!o_win()&&!x_win()&&abs(cnto-cntx)<=1){
if(cntx==cnto){
printf("X's turn\n");
continue;
}
else if(cnto+1==cntx){
printf("O's turn\n");
continue;
}
}
printf("Illegal Situation\n");
}
}
return 0;
}
/**
5
...
XX.
..O
XOX
XXO
OXO
.O.
XO.
.O.
XOX
OX.
X.O
XXX
OOO
...
**/