首页 新闻 会员 周边

算法: 一字棋问题求解

0
悬赏园豆:5 [已解决问题] 解决于 2012-03-23 15:12

一字棋AB两名棋手交替在3*3的棋盘上下棋,轮到谁走棋谁就往空格上放一只自己的棋子,先使自己的棋子构成三子成一线”(同一行或列或对角线全是某人的棋子)者取得了胜利,若九个格子全部被下满而未出现三子成一线,则判为平局。每局由A选手首先下。

给出一个尚未下完的棋局,请你帮助下一位下棋的棋手判断是否能在下一回合取胜。

 

 

第一行给出整数T(1<=T<=100),表示有T个棋局需要判断,接下来给出T3x3矩阵表示当前棋局,1代表是选手A的棋子,2代表是选手B的棋子,0代表该该格子尚未放置棋子。每个棋局里同一行的3个数用空格隔开,每个棋局之间有一空行。

输入的棋局保证是一个合法的(在正常游戏中可能出现的)未下完的棋局

 

 

每行输出一个棋局的答案。若下一位选手能够在下一轮中取胜则输出“YES”

否则输出“NO”

Input

 

3
2 1 1
2 0 0
0 1 0
 
1 0 2
0 2 0
0 0 1
 
2 1 1
2 0 0
0 0 0
 
Output 
YES
NO
NO

 

 

warm3snow的主页 warm3snow | 菜鸟二级 | 园豆:391
提问于:2012-03-21 23:22
< >
分享
最佳答案
0

木有回答的动力-_-!

收获园豆:3
zsounder | 老鸟四级 |园豆:2819 | 2012-03-22 15:11

??

warm3snow | 园豆:391 (菜鸟二级) | 2012-03-22 16:22

@informatics: 帮帮忙吧, 我是acm新手。。。

warm3snow | 园豆:391 (菜鸟二级) | 2012-03-22 16:25

@informatics: 

其实这个问题应该看看MinMax的,我这里写一个最笨的方法:

 1 bool h_1(int arrayfic[3][3])
2 {
3 return (arrayfic[0][0]==arrayfic[0][1])&&(arrayfic[0][0]==arrayfic[0][2]);
4 }
5
6 bool h_2(int arrayfic[3][3])
7 {
8 return (arrayfic[1][0]==arrayfic[1][1])&&(arrayfic[1][0]==arrayfic[1][2]);
9 }
10
11 bool h_3(int arrayfic[3][3])
12 {
13 return (arrayfic[2][0]==arrayfic[2][1])&&(arrayfic[2][0]==arrayfic[2][2]);
14 }
15
16 bool v_1(int arrayfic[3][3])
17 {
18 return (arrayfic[0][0]==arrayfic[1][0])&&(arrayfic[0][0]==arrayfic[2][0]);
19 }
20 bool v_2(int arrayfic[3][3])
21 {
22 return (arrayfic[0][1]==arrayfic[1][1])&&(arrayfic[0][1]==arrayfic[2][1]);
23 }
24 bool v_3(int arrayfic[3][3])
25 {
26 return (arrayfic[0][2]==arrayfic[1][2])&&(arrayfic[0][2]==arrayfic[2][2]);
27 }
28
29 bool lt_br(int arrayfic[3][3])
30 {
31 return (arrayfic[0][0]==arrayfic[1][1])&&(arrayfic[0][0]==arrayfic[2][2]);
32 }
33
34 bool lb_tr(int arrayfic[3][3])
35 {
36 return (arrayfic[0][2]==arrayfic[1][1])&&(arrayfic[0][2]==arrayfic[2][0]);
37 }
38
39
40 bool win(int arrayfic[3][3]){
41 int count1 = 0, count2 = 0;
42 bool player1 = false;
43
44 for(int i=0; i<3; ++i)
45 for(int j=0; j<3; ++j)
46 (arrayfic[i][j]==1)?++count1:++count2;
47 count1<=count2?player1=true:player1=false;
48
49 for(int i=0; i<3; ++i)
50 {
51 for(int j=0; j<3; ++j)
52 {
53 if(!arrayfic[i][j])
54 {
55 arrayfic[i][j] = player1?1:2;
56 if(i==0&&j==0){ if(h_1(arrayfic)||v_1(arrayfic)||lt_br(arrayfic))return true; arrayfic[i][j] = 0;continue;}
57 if(i==0&&j==1){ if(h_1(arrayfic)||v_2(arrayfic))return true; arrayfic[i][j] = 0;continue;}
58 if(i==0&&j==2){ if(h_1(arrayfic)||v_3(arrayfic)||lb_tr(arrayfic))return true; arrayfic[i][j] = 0;continue;}
59 if(i==1&&j==0){ if(v_1(arrayfic)||h_2(arrayfic))return true; arrayfic[i][j] = 0;continue;}
60 if(i==1&&j==1){ if(h_2(arrayfic)||v_2(arrayfic)||lt_br(arrayfic)||lb_tr(arrayfic))return true; arrayfic[i][j] = 0;continue;}
61 if(i==1&&j==2){ if(h_2(arrayfic)||v_3(arrayfic))return true; arrayfic[i][j] = 0;continue;}
62 if(i==2&&j==0){ if(v_1(arrayfic)||h_3(arrayfic)||lb_tr(arrayfic))return true; arrayfic[i][j] = 0;continue;}
63 if(i==2&&j==1){ if(h_3(arrayfic)||v_2(arrayfic))return true; arrayfic[i][j] = 0;continue;}
64 if(i==2&&j==2){ if(h_3(arrayfic)||v_3(arrayfic)||lt_br(arrayfic))return true; arrayfic[i][j] = 0;continue;}
65
66 }
67 }
68 }
69
70 return false;
71 }



测试代码

zsounder | 园豆:2819 (老鸟四级) | 2012-03-22 18:10

@Wang Hui: 构造一下边界,就不用写很多if了。

水牛刀刀 | 园豆:6350 (大侠五级) | 2012-03-22 18:30

@水牛刀刀: 

呵呵,构造边界自然可以,不过做if是因为:针对不同的位置,可以形成三子成一线的条件都不是很多,也就几条路径,没有必要每一个位置都去做8方向的计算,那样比较耗时。因为位置不是很多,所以直接if一下,针对不同的位置只对几个路径做检测。

zsounder | 园豆:2819 (老鸟四级) | 2012-03-22 18:34
其他回答(1)
0

总是构造这样一个7*7矩阵(2维数组),外圈全为9,中心3*3为输入数据(在输入赋值过程中,将2的格子赋值为9)。这样9表示不能放置棋子的位置,1表示已有棋子,0表示可放置。整个问题转化为:遍历中心3*3一共9个格子,对这个格子,求出它8个方向的数字和,若某个方向和为2,则输出YES,结束后还没找到则输出NO。构造外圈矩阵只是为了计算8个方向时不用考虑越界,如果你只构造3*3矩阵也是可以的,这样你需要很多if语句去判断是否会越界。(当然3*3矩阵理论上效率高,但是容易出错)

收获园豆:2
水牛刀刀 | 园豆:6350 (大侠五级) | 2012-03-22 10:44

还是看不出如何解决这个问题,不过还是谢谢你了。。

支持(0) 反对(0) warm3snow | 园豆:391 (菜鸟二级) | 2012-03-22 12:32

@informatics: 哪句看不懂?

支持(0) 反对(0) 水牛刀刀 | 园豆:6350 (大侠五级) | 2012-03-22 18:28
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册