F -Ouths andCrosses
Crawling in
process...Crawling failedTime Limit:1000MSMemory Limit:65536KB64bit IO Format:%I64d & %I64u
URAL 1195
Description
The OlympicWinter Games. The Ouths and Crosses on the 3×3 Board Event. The Panel of Judgesreceived an unfinished game with 3 moves made by each player. The playerscouldn't continue the game because they had lost too much blood at the dopingcontrol. The Panel of Judges had to determine the outcome in the case of theoptimal play of both parties.
Since there wereas many crosses as ouths, the Panel of Judges wanted to decide that it was adraw. However, Head Judge observed that one player was able to win the game inone move. Your task is to determine the outcome in the case of the optimal playof both rivals. According to the International Rules, Crosses move first in thegame and the winner is he who puts three of his symbols in the same row,column, or diagonal.
Input
The inputcontains a 3×3 table consisting of the symbols X, O (the capital Englishletters, which mark the moves of Crosses and Ouths), and # (this symbol denotesan empty field). The table contains exactly three Crosses and three Ouths. Itis guaranteed that the game is not finished, i.e. any row, column or diagonalcontains neither three Crosses nor three Ouths.
Output
If Crosses win the game, output “Crosses win”.If Ouths win, output “Ouths win”. In the case of a draw, output “Draw”.
Sample Input
XXO
#X#
#OO
Ouths win
O#O
#X#
XOX
Draw
题目翻译:
描述
冬季奥运会。3×3棋盘上的圈和叉比赛。评委们接到一个未结束的比赛,这个比赛还剩3步供两个玩家轮流下子。两个选手因为已经失去了太多控制局面的机会而无法继续比赛。评委小组必须在双方选手都下出最好的棋的情况下确定比赛的最终结果。
因为有许多叉和圈在棋盘上,评委小组想判这场比赛平局。然而,评委长注意到一个选手在一步棋内能赢得这场比赛。你的任务是在双方选手都下出最好的棋的情况下确定输赢。根据国际规则,叉是首先下子的,某一玩家有三个棋子在同一行、列、或对角线上即是胜利。
输入
输入包含一个3×3的棋盘,其中包括符号X、O(为大写英文字母的X和O),和#(表示这个格子没有任何棋子)。输入棋局保证包含三个叉和三个圈。保证游戏没有结束,即任意行、列或对角线没有连续的三个棋子。
输出
如果叉赢得比赛,则输出“Crosses win”。如果圈赢得比赛,输出“Ouths win”。如果是平局的情况,则输出“Draw”。
思路:
题目给出一个井字棋残局,包含3个X、3个O和3个空余格,规定X先走棋;
井字棋的胜利条件,即是列、行、对角线共8条线任意一条3子连成一线;
在井字棋中,轮到一方走子,如果我方有至少1中赢的情况(即2子差1子就连成一线)我方必赢;如果我方没有赢的情况,而对方有至少2中赢的情况,我方最多只能堵其中一种,必输,对方必赢;如果双方都没有赢的情况,或者对方只有一种赢的情况(我方下子去堵),便进入模拟,找到最优走子;
最优走子即是,保证对方不会有赢的情况,同时我方有尽量多的赢的情况(让对方堵不来);
如果双方都没有必赢的情况,则该局平局
代码:
#include
usingnamespacestd;
boolwinO=false;
boolwinX=false;//表示X,O是否赢了
intO,X;//表示O,X有多少种赢得可能
charbuf[3][4];//棋盘
voidcheck()//统计O,X有没有赢的情况(差1颗子就连成一线),共8种可能
{
O=0;
X=0;
//归零O,X
inttx,to;
for(inti=0;i<3;++i)
{
to=0;
tx=0;
for(intj=0;j<3;++j)
{
if(buf[i][j]=='X')
++tx;
elseif(buf[i][j]=='O')
++to;
}
if(tx==2 && to==0)
++X;
elseif(to==2&& tx==0)
++O;
}
//横着的3条线
for(inti=0;i<3;++i)
{
to=0;
tx=0;
for(intj=0;j<3;++j)
{
if(buf[j][i]=='X')
++tx;
elseif(buf[j][i]=='O')
++to;
}
if(tx==2 && to==0)
++X;
elseif(to==2&& tx==0)
++O;
}
//竖着的3条线
tx=0;
to=0;
for(inti=0;i<3;++i)
{
if(buf[i][i]=='X')
++tx;
elseif(buf[i][i]=='O')
++to;
}
if(tx==2&& to==0)
++X;
elseif(to==2 && tx==0)
++O;
//左上到右下的1条线
tx=0;
to=0;
for(inti=0;i<3;++i)
{
if(buf[i][2-i]=='X')
++tx;
elseif(buf[i][2-i]=='O')
++to;
}
if(tx==2&& to==0)
++X;
elseif(to==2 && tx==0)
++O;
//右上到左下的1条线
//printf("%d
%d\n",X,O);
return;
}
voidsolve(charth)//模拟走棋情况
{
if(th=='X')//X走子
{
if(O>=2)//如果O有至少2种赢的情况,堵不住,O必赢
winO=true;
elseif(O==1)//O只有1种赢得情况,必须堵,堵到之后走,继续模拟走子
{
boolok=false;//表示是否堵到
for(inti=0;i<3&& !ok;++i)
for(intj=0;j<3&& !ok;++j)//找到每一个#,即空位
if(buf[i][j]=='#')
{
buf[i][j]=th;//下子
check();//检查X、O赢的情况
if(O==0)//如果堵住,继续轮到O走子
{
ok=true;
solve('O');
}
buf[i][j]='#';
}
}
else//如果O没有赢的情况,X走子随意,递归回溯找最优的走子
{
for(inti=0;i<3;++i)
for(intj=0;j<3;++j)
if(buf[i][j]=='#')
{
buf[i][j]=th;
check();
solve('O');
buf[i][j]='#';
}
}
}
if(th=='O')//O走子,和X同理
{
if(X>=2)
winX=true;
elseif(X==1)
{
boolok=false;;
for(inti=0;i<3&& !ok;++i)
for(intj=0;j<3&& !ok;++j)
if(buf[i][j]=='#')
{
buf[i][j]=th;
check();
if(X==0)
{
ok=true;
solve('X');
}
buf[i][j]='#';
}
}
else
{
for(inti=0;i<3;++i)
for(intj=0;j<3;++j)
if(buf[i][j]=='#')
{
buf[i][j]=th;
check();
solve('X');
buf[i][j]='#';
}
}
}
}
intmain()
{
for(inti=0;i<3;++i)
scanf("%s",buf[i]);
check();//对输入进行判断
if(X>=1)//X先走棋,如果有至少1种赢的可能,走即可,X必赢
winX=true;
elseif(O>=2)//在X没有赢的可能的情况下,如果O有至少2中赢的可能,X只能堵一种,O必赢
winO=true;
else//上述两种情况都没有,进入模拟
solve('X');
//最后,如果根据winX、winO判断输出
if(winX)
printf("Crosses win\n");
elseif(winO)
printf("Ouths win\n");
else
printf("Draw\n");
return0;
}
�����U�~;�w