一、题目 : 井字棋
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
小武是井字棋的忠实粉丝,井字棋,又称为井字游戏、井字过三关等,是种纸笔游戏。其具体玩法为:
两个玩家,一个打圈(O),一个打叉(X),轮流在3乘3的格上打自己的符号,最先以横、直、斜连成一线则为胜。当9个格子画满,双方均无法取胜时,则为和局。当有玩家取胜或者下成平局后,比赛结束。
假设每次X方均为先手,给出一个局面,请你判断这个局面是否合法,如果局面合法,则判断当前局面是否是比赛结束局面,如果是,则判断当前局面是X方胜利,O方胜利或者是平局。如果局面暂时未分胜负,则判断下一个下棋的选手下完一步后(假设采用最优策略)能否取胜。
输入
每个输入数据包含多个测试点。
第一行为测试点的个数S <= 2000。之后是S个测试点的数据。
每个测试点的数据包括3行,用于描述整个棋盘。每行包含一个长度为3的字符串,取值范围为{'_', 'O', 'X'},其中'_'表示该格子为空,'X'表示该格被先手者占领,'O'表示该格被后手者占领。
每个测试点之间会有一个空行相隔。
输出
对于每个测试点,对应的结果输出一行。
如果局面非法,则输出"Invalid"。
否则如果局面是比赛结束局面,X取胜则输出"X win", O取胜则输出"O win", 如果是平局则输出"Draw"。
如果局面合法并且不是比赛结束的局面,则判断下一个下棋的选手下完一步后能否取胜,如果可以,则输出"Next win", 否则输出"Next cannot win"。
注意,所有的结果输出均不带引号。
样例提示
第一个例子,因为X先下,所以该局面不可能出现。
第二个例子,为结束局面,X取胜。
第三个例子,全部格子下完,双方均无法取胜,平局。
第四个例子,局面未分胜负,下一个下的是X,可以取胜。
第五个例子,局面未分胜负,下一个下的是O,无论下到哪一个格子均无法取胜。
样例输入
5
__O
_XO
___
XXX
___
OO_
XXO
OOX
XXO
X_X
OO_
___
XO_
XX_
__O
样例输出
Invalid
X win
Draw
Next win
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
小武是井字棋的忠实粉丝,井字棋,又称为井字游戏、井字过三关等,是种纸笔游戏。其具体玩法为:
两个玩家,一个打圈(O),一个打叉(X),轮流在3乘3的格上打自己的符号,最先以横、直、斜连成一线则为胜。当9个格子画满,双方均无法取胜时,则为和局。当有玩家取胜或者下成平局后,比赛结束。
假设每次X方均为先手,给出一个局面,请你判断这个局面是否合法,如果局面合法,则判断当前局面是否是比赛结束局面,如果是,则判断当前局面是X方胜利,O方胜利或者是平局。如果局面暂时未分胜负,则判断下一个下棋的选手下完一步后(假设采用最优策略)能否取胜。
输入
每个输入数据包含多个测试点。
第一行为测试点的个数S <= 2000。之后是S个测试点的数据。
每个测试点的数据包括3行,用于描述整个棋盘。每行包含一个长度为3的字符串,取值范围为{'_', 'O', 'X'},其中'_'表示该格子为空,'X'表示该格被先手者占领,'O'表示该格被后手者占领。
每个测试点之间会有一个空行相隔。
输出
对于每个测试点,对应的结果输出一行。
如果局面非法,则输出"Invalid"。
否则如果局面是比赛结束局面,X取胜则输出"X win", O取胜则输出"O win", 如果是平局则输出"Draw"。
如果局面合法并且不是比赛结束的局面,则判断下一个下棋的选手下完一步后能否取胜,如果可以,则输出"Next win", 否则输出"Next cannot win"。
注意,所有的结果输出均不带引号。
样例提示
第一个例子,因为X先下,所以该局面不可能出现。
第二个例子,为结束局面,X取胜。
第三个例子,全部格子下完,双方均无法取胜,平局。
第四个例子,局面未分胜负,下一个下的是X,可以取胜。
第五个例子,局面未分胜负,下一个下的是O,无论下到哪一个格子均无法取胜。
样例输入
5
__O
_XO
___
XXX
___
OO_
XXO
OOX
XXO
X_X
OO_
___
XO_
XX_
__O
样例输出
Invalid
X win
Draw
Next win
Next cannot win
二、个人解答代码
<pre name="code" class="cpp">
<pre name="code" class="cpp">#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
int s,i,j,k,countX,countO,curX,curY;
cin>>s;
vector<string> maxtrix;
//只要判断五个位置是否可以构成3个相连
vector<pair<int,int>> query;
query.push_back(make_pair(0,0));
query.push_back(make_pair(0,1));
query.push_back(make_pair(0,2));
query.push_back(make_pair(1,0));
query.push_back(make_pair(2,0));
string str;
bool flag;
for(i=0;i<s;i++)
{
maxtrix.clear();
flag=false;
countX=countO=0;
//读入数据
for(j=0;j<3;j++)
{
cin>>str;
maxtrix.push_back(str);
//分别统计X、O的数目
for(k=0;k<3;k++)
{
if(str[k]=='X')
countX++;
else if(str[k]=='O')
countO++;
}
}
//如果X的数目大于等于O的数目说明合法,否则输出不合法
if(countX>=countO)
{ //判断当前是否是结束局
for(j=0;j<5;j++)
{
curX=query[j].first,curY=query[j].second;
if(maxtrix[curX][curY]=='X'||maxtrix[curX][curY]=='O')
{
//判断横、竖、斜是否有三个一样的X或者O
if((curX+2<3&&maxtrix[curX][curY]==maxtrix[curX+1][curY]&&maxtrix[curX+2][curY]==maxtrix[curX][curY])||
(curY+2<3&&maxtrix[curX][curY]==maxtrix[curX][curY+1]&&maxtrix[curX][curY]==maxtrix[curX][curY+2])||
(curX+2<3&&curY+2<3&&maxtrix[curX][curY]==maxtrix[curX+1][curY+1]&&maxtrix[curX+2][curY+2]==maxtrix[curX][curY])||
(curX-2>=0&&curY-2>=0&&maxtrix[curX][curY]==maxtrix[curX-1][curY-1]&&maxtrix[curX-2][curY-2]==maxtrix[curX][curY]))
{
if(maxtrix[curX][curY]=='X')
cout<<"X win"<<endl;
else
cout<<"O win"<<endl;
flag=true;
break;
}
}
}
//如果是结束局,读入下一组数据
if(flag)
continue;
//如果不是结束局,则判断当前是否已经满格,如果是的话,输出平局,否则判断下一个是否能赢
if(countX+countO==9)
{
cout<<"Draw"<<endl;
}
else
{//判断下一个是X的情况
if(countX==countO)
{
for(j=0;j<5;j++)
{
curX=query[j].first,curY=query[j].second;
if(maxtrix[curX][curY]=='X')
{//如果当前位置是X,并且判断横竖斜是否存在添一个满足赢条件
if((curX+2<3&&((maxtrix[curX][curY]==maxtrix[curX+1][curY]&&maxtrix[curX+2][curY]=='_')||(maxtrix[curX+2][curY]==maxtrix[curX][curY]&&maxtrix[curX+1][curY]=='_')||(maxtrix[curX+2][curY]==maxtrix[curX+1][curY]&&maxtrix[curX][curY]=='_')))
||(curY+2<3&&((maxtrix[curX][curY]==maxtrix[curX][curY+1]&&maxtrix[curX][curY+2]=='_')||(maxtrix[curX][curY+2]==maxtrix[curX][curY]&&maxtrix[curX][curY+1]=='_')||(maxtrix[curX][curY+2]==maxtrix[curX][curY+1]&&maxtrix[curX][curY]=='_')))
||(curX+2<3&&curY+2<3&&((maxtrix[curX][curY]==maxtrix[curX+1][curY+1]&&maxtrix[curX+2][curY+2]=='_')||(maxtrix[curX+2][curY+2]==maxtrix[curX][curY]&&maxtrix[curX+1][curY+1]=='_')||(maxtrix[curX+2][curY+2]==maxtrix[curX+1][curY+1]&&maxtrix[curX][curY]=='_')))
||(curX-2>=0&&curY-2>=0&&((maxtrix[curX][curY]==maxtrix[curX-1][curY-1]&&maxtrix[curX-2][curY-2]=='_')||(maxtrix[curX-2][curY-2]==maxtrix[curX][curY]&&maxtrix[curX-1][curY-1]=='_')||(maxtrix[curX-2][curY-2]==maxtrix[curX-1][curY-1]&&maxtrix[curX][curY]=='_'))))
{
cout<<"Next win"<<endl;
flag=true;
break;
}
}
}
}
else//判断下一个是O的情况
{
for(j=0;j<5;j++)
{
curX=query[j].first,curY=query[j].second;
if(maxtrix[curX][curY]=='O')
{
//如果当前位置是O,并且判断横竖斜是否存在添一个满足赢条件
if((curX+2<3&&((maxtrix[curX][curY]==maxtrix[curX+1][curY]&&maxtrix[curX+2][curY]=='_')||(maxtrix[curX+2][curY]==maxtrix[curX][curY]&&maxtrix[curX+1][curY]=='_')||(maxtrix[curX+2][curY]==maxtrix[curX+1][curY]&&maxtrix[curX][curY]=='_')))||
(curY+2<3&&((maxtrix[curX][curY]==maxtrix[curX][curY+1]&&maxtrix[curX][curY+2]=='_')||(maxtrix[curX][curY+2]==maxtrix[curX][curY]&&maxtrix[curX][curY+1]=='_')||(maxtrix[curX][curY+2]==maxtrix[curX][curY+1]&&maxtrix[curX][curY]=='_')))||
(curX+2<3&&curY+2<3&&((maxtrix[curX][curY]==maxtrix[curX+1][curY+1]&&maxtrix[curX+2][curY+2]=='_')||(maxtrix[curX+2][curY+2]==maxtrix[curX][curY]&&maxtrix[curX+1][curY+1]=='_')||(maxtrix[curX+2][curY+2]==maxtrix[curX+1][curY+1]&&maxtrix[curX][curY]=='_')))||
(curX-2>=0&&curY-2>=0&&((maxtrix[curX][curY]==maxtrix[curX-1][curY-1]&&maxtrix[curX-2][curY-2]=='_')||(maxtrix[curX-2][curY-2]==maxtrix[curX][curY]&&maxtrix[curX-1][curY-1]=='_')||(maxtrix[curX-2][curY-2]==maxtrix[curX-1][curY-1]&&maxtrix[curX][curY]=='_'))))
{
cout<<"Next win"<<endl;flag=true;break;
}
}
}
}
//如果下一手不能满足赢条件,则输出不能赢
if(!flag)
cout<<"Next cannot win"<<endl;
}
}
else
{
cout<<"Invalid"<<endl;
}
}
system("pause");
return 0;
}