哈理工OJ P2320:OX

题目链接:OX

题意 :给出一个3X3的黑白棋棋盘,棋盘上有若干黑白子,再给出下一个下的人,问下一个下的人能否赢

分析:考虑到只有39种状态,故用一个数保存目前棋盘的状态,记为value,再枚举空位DFS,每次

DFS先判该状态是否已到达(剪枝),再拆分状态用c[3][3]储存,判断是否有赢的状态,最后遍历

棋盘寻找空位,若有则下,value储存状态,再DFS下去,注意返回c[i][j]清零

判断胜负平的条件如下:

  若有一个状态可以到达必败点,则该点必胜,返回1

  若有一个状态可以到达平局点,则该点平局,返回-1

  否则必败,返回0

详情见代码

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=1e5+10;
 6 int t,dp[maxn][3],st;
 7 char s[3];
 8
 9 int dfs(int value,int st)
10 {
11     if(dp[value][st]!=-2) return dp[value][st];
12     int c[3][3],sum=0,n1=0,n2=0;//memset(c,0,sizeof(c));
13     for(int i=0;i<3;++i)for(int j=0;j<3;++j)
14     {
15         c[i][j]=value%3;value/=3;
16         if(c[i][j]) sum++;
17     }
18     for(int i=0;i<3;++i)
19     {
20         if(c[i][0]==c[i][1]&&c[i][1]==c[i][2]) if(c[i][0]==1) n1=1;else if(c[i][0]==2) n2=1;
21         if(c[0][i]==c[1][i]&&c[1][i]==c[2][i]) if(c[0][i]==1) n1=1;else if(c[0][i]==2) n2=1;
22     }
23     if(c[0][0]==c[1][1]&&c[1][1]==c[2][2]) if(c[1][1]==1) n1=1;else if(c[1][1]==2) n2=1;
24     if(c[0][2]==c[1][1]&&c[1][1]==c[2][0]) if(c[1][1]==1) n1=1;else if(c[1][1]==2) n2=1;
25     if(n1&&st==1) return 1;
26     if(n2&&st==1) return 0;
27     if(n1&&st==2) return 0;
28     if(n2&&st==2) return 1;
29     if(sum==9) return -1;
30     int judge=0;
31     for(int i=0;i<3;++i)for(int j=0;j<3;++j) if(c[i][j]) continue;
32     else
33     {
34         int value=0;
35         c[i][j]=st;
36         for(int p=0;p<3;++p)for(int k=0;k<3;++k) value=value*3+c[p][k];
37         c[i][j]=0;//很重要,返回时清0
38         int ans=dfs(value,3-st);
39         if(ans==0) return 1;//可以到达必败点的为必胜点
40         if(ans==-1) judge=1;//可以到达平局的状态返回平局
41     }
42     if(judge) return -1;else return 0;//否则返回必败点
43 }
44 int main()
45 {
46     for(scanf("%d",&t);t--;)
47     {
48         for(int i=0;i<maxn;++i)for(int j=0;j<3;++j) dp[i][j]=-2;
49         int value=0;
50         for(int i=0;i<3;++i)for(int j=0;j<3;++j)
51         {
52             scanf("%s",s);
53             if(s[0]==‘o‘) value=value*3+2;
54             else if(s[0]==‘x‘) value=value*3+1;
55             else value=value*3;
56         }
57         scanf("%s",s);
58         if(s[0]==‘x‘) st=1;else st=2;
59         int ans=dfs(value,st);
60         if(ans==0) printf("%c win!\n",st==1?‘o‘:‘x‘);
61         else if(ans==1) printf("%c win!\n",st==2?‘o‘:‘x‘);
62         else puts("tie!");
63     }
64 }

时间: 2024-12-14 08:53:52

哈理工OJ P2320:OX的相关文章

二叉树的建立与遍历(山东理工OJ)

数据结构实验之二叉树的建立与遍历 题目描述 已知一个按先序序列输入的字符序列,如abc,,de,g,,f,,,(其中逗号表示空节点).请建立二叉树并按中序和后序方式遍历二叉树,最后求出叶子节点个数和二叉树深度. 输入 输入一个长度小于50个字符的字符串. 输出 输出共有4行: 第1行输出中序遍历序列: 第2行输出后序遍历序列: 第3行输出叶子节点个数: 第4行输出二叉树深度. 示例输入 abc,,de,g,,f,,, 示例输出 cbegdfa cgefdba 3 5 #include <iost

众数问题(山东理工OJ)

题目描写叙述 给定含有n个元素的多重集合S,每一个元素在S中出现的次数称为该元素的重数.多重集S中重数最大的元素称为众数. 比如,S={1,2,2,2,3.5}.多重集S的众数是2,其重数为3. 对于给定的由n 个自然数组成的多重集S.计算S的众数及其重数. 输入 输入数据的第1行是多重集S中元素个数n(n<1300000):接下来的n行中,每行有一个最多含有5位数字的自然数,. 输出 输出数据的第1行给出众数,第2行是重数. 演示样例输入 6 1 2 2 2 3 5 演示样例输出 2 3 #i

哈理工 oj 2122 旅行(map + 最短路dij算法)

旅行 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 18(6 users) Total Accepted: 3(3 users) Rating: Special Judge: No Description "04.24,和Sakura去东京天空树,世界上最暖和的地方天空树的顶上. " "04.26.和Sakura去明治神宫.有人在那里举办婚礼." "04.25.和Sakura去迪士尼.鬼屋非

哈理工 oj——队列列列列!!!!!

队列列列列!!!!! Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 337(148 users) Total Accepted: 154(142 users) Rating: Special Judge: No Description xuxu完成了栈的实验要求后,他又很是开心,刚要出去liuda, biaobiao突然问道老师让做的队列的那个实验你写完了么,xuxu顿时大呼悲哉....他给忘记了,怎么办..明天就要上交实验报告了

哈理工 oj 1161 Leyni

Leyni Time Limit: 3000 MS Memory Limit: 65536 K Total Submit: 466(94 users) Total Accepted: 142(88 users) Rating: Special Judge: No Description Leyni被人掳走,身在水深火热之中... 小奈叶为了拯救Leyni,独自一人前往森林深处从静竹手中夺回昏迷中的Leyni. 历经千辛万苦,小奈叶救出了Leyni,但是静竹为此极为恼怒,决定对他们发起最强烈的进攻

哈理工 oj 2189 节点的连接

节点的连接 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 67(36 users) Total Accepted: 36(34 users) Rating: Special Judge: No Description 有N个节点,一开始任意两个节点都没有相连,之后有两种操作: 1: 将 A 节点和 B 节点连接起来. 2: 问从A节点出发可以直接或间接到达的节点数量. 如果 A 节点和 B 节点被连接起来了,那么从A可以到达B,同

南阳理工OJ之三个数从小到大排序

------------------------------------------- AC代码: 1 import java.util.Arrays; 2 import java.util.Scanner; 3 4 public class Main { 5 6 public static void main(String[] args) { 7 8 Scanner sc=new Scanner(System.in); 9 10 int x[]=new int[3]; 11 for(int i

南阳理工OJ之字符串逆序输出

------------------------------------------- AC代码: 1 import java.util.Scanner; 2 3 public class Main { 4 5 public static void main(String[] args) { 6 7 Scanner sc=new Scanner(System.in); 8 9 int times=Integer.parseInt(sc.nextLine()); 10 while(times-->

南阳理工OJ之喷水装置(一)

---------------------------------------------------------------------------- AC代码: 1 import java.util.Arrays; 2 import java.util.Scanner; 3 4 public class Main { 5 6 public static void main(String[] args) { 7 8 Scanner sc=new Scanner(System.in); 9 in