参考链接:https://www.cnblogs.com/nwpuacmteams/articles/5697873.html

极小极大搜索 的个人理解(alpha-beta剪枝):https://www.cnblogs.com/Mathics/p/4100059.html

代码+注释:

  1 #include<cstdio>
2 using namespace std;
3
4 //10个顶点之间的连线编号
5 /*
6 就比如下面这个矩阵的1,他所代表的边就是1号点与3号点的连线
7 */
8 int mat[11][11]=
9 {
10 {0,0,0,0,0,0,0,0,0,0,0},
11 {0,0,0,1,0,0,0,0,0,0,0},
12 {0,0,0,2,3,4,0,0,0,0,0},
13 {0,1,2,0,0,5,6,0,0,0,0},
14 {0,0,3,0,0,7,0,9,10,0,0},
15 {0,0,4,5,7,0,8,0,11,12,0},
16 {0,0,0,6,0,8,0,0,0,13,14},
17 {0,0,0,0,9,0,0,0,15,0,0},
18 {0,0,0,0,10,11,0,15,0,16,0},
19 {0,0,0,0,0,12,13,0,16,0,17},
20 {0,0,0,0,0,0,14,0,0,17,0}
21 };
22
23 //9个三角形组成的边状态压缩一下
24 /*
25 比如一个三角形是由1,2,3号边构成(这个边的编号我们在上卖弄的矩阵说过了)
26 那么他们所压缩成的数是(1<<1)|(1<<2)|(1<<3) ('|'是一种运算符号)
27 */
28 int tri[9]= {7,152,52,352,34304,3200,71680,12544,155648};
29 int STATUS=(1<<18)-1;
30
31 int Get_New_Status(int old,int edge,int &cnt) //在旧状态下改变后新的状态
32 {
33 int now=old|edge;
34 for(int i=0;i<9;++i)
35 {
36 if((now&tri[i])==tri[i] && (old&tri[i])!=tri[i])
37 {
38 cnt++;
39 }
40 }
41 return now;
42 }
43
44 int MaxSearch(int state,int alpha,int ca,int cb);
45 int MinSearch(int state,int beta,int cnt_a,int cnt_b) //当执行这个函数也就是该B方下棋
46 {
47 if(cnt_a==5) return 1;
48 if(cnt_b==5) return -1;
49 if(state==STATUS && cnt_a>cnt_b) return 1;
50 else if(state==STATUS && cnt_a<cnt_b) return -1;
51 int ans=1; //因为极小搜索要获取的是最小值(返回值只可能是1或-1,所以这里我们设为1就行)
52 int remain=(~state)&STATUS;
53 while(remain)
54 {
55 int edge=remain&(-remain); //枚举每一条边
56 int new_a=cnt_a,new_b=cnt_b;
57 int now=Get_New_Status(state,edge,new_b),temp;
58 if(new_b>cnt_b)
59 temp=MinSearch(now,beta,cnt_a,new_b); //返回值是1代表A获胜,否则B获胜
60 else temp=MaxSearch(now,ans,cnt_a,new_b); //只不过Maxsearch会尽可能返回大值,Minsearch尽可能返回小值
61 /*
62 上面传参传的ans,这个参数的目的是用来限制对于B这一步棋无谓的搜索,他代表的意思是
63 B所以的着法中,那个最好的着法的得分
64
65 因为B是得分越小越有可能赢(A与其相反)
66
67 比如这个时候B传过去一个1,然后对于B这一步得下一步得第一次试探,就返回一个-1,也就是说B赢了,那么不用
68 进行B这一步得下一步得第二次第三次或更多次试探
69
70 其实你的思想不用去不停的递归,看一层就可以
71 */
72 if(temp<ans) ans=temp;
73 if(temp<=beta) return ans;
74 remain-=edge;
75 }
76 return ans;
77 }
78
79 int MaxSearch(int state,int alpha,int ca,int cb)
80 {
81 //出现5个三角形,胜负已分
82 if(ca>=5) return 1;
83 if(cb>=5) return -1;
84 //所有的边都取了,游戏也结束
85 if(state==STATUS) return ca>cb?1:-1;
86 int ans=-1;
87 int remain=(~state)&STATUS; //剩下还有哪些边可以取
88 while(remain)
89 {
90 /*
91 & 是 按位与运算符
92 -x 是x 的补码;补码为取反+1
93 x&(-x)就是取出来x二进制形式下的最小位权那个1
94 */
95 int seg=remain&(-remain); //枚举
96
97 int ta=ca,tb=cb;
98 int now=Get_New_Status(state,seg,ta),tmp;
99 //是否有新的三角形生成
100 if(ta>ca) tmp=MaxSearch(now,alpha,ta,cb);
101 else tmp=MinSearch(now,ans,ta,cb);
102 if(tmp>ans) ans=tmp;
103 //alpha剪枝
104 if(tmp>=alpha) return ans;
105 remain-=seg;
106 }
107 return ans;
108 }
109
110 int main()
111 {
112 int t,cas=0;
113 scanf("%d",&t);
114 while(t--)
115 {
116 int n,u,v;
117 scanf("%d",&n);
118 //已经走了多少步,当前边的状态
119 int cnt=0,state=0;
120 //两个人分别有几个三角形
121 int ca=0,cb=0;
122 while(n--)
123 {
124 scanf("%d%d",&u,&v);
125 int ta=ca,tb=cb;
126 state=Get_New_Status(state,1<<mat[u][v],(cnt&1)?cb:ca);
127 //没有新的三角形,
128 if(ta==ca&&tb==cb)
129 cnt++;
130 }
131 int ans;
132 /*
133 当调用依次MinSearch或者MaxSearch函数的时候,其实他已经把这个局势下所有情况都试了一遍
134 同时因为题目上没有说平局输出什么,所以我们也不需要去管(其实也可以管,加一个判断就可以)
135 */
136 if(cnt&1)
137 ans=MinSearch(state,-1,ca,cb);
138 else
139 ans=MaxSearch(state,1,ca,cb);
140
141 printf("Game %d: %c wins.\n",++cas,ans==1?'A':'B');
142 }
143 return 0;
144 }

最新文章

  1. JavaScript:让浏览器全屏显示
  2. instanceof 运算符
  3. WPF根据Oracle数据库的表,生成CS文件小工具
  4. 地图、定位 CLLocationManager CLGeocoder CLPlacemark
  5. 重构if...else...或者switch程序块
  6. HDU 1505 City Game (hdu1506 dp二维加强版)
  7. spring mvc和spring配置扫描包问题
  8. windows下pip升级到8.1.2
  9. jetty 8.x, 9.x无法加载jstl的PWC6188问题
  10. MyEclipse 利用反向功能生成Java 实体类
  11. 【开发】Form Validate 表单验证 扩展应用
  12. linux mysql密码破解一张图解释
  13. SolrCloud简介
  14. Necklace(树状数组+离线操作)
  15. ajax中设置contentType: “application/json”的作用
  16. 再回首UML之上篇
  17. visualvm监控类是否是多例模式
  18. 传入mybatis的xml为Long型时报There is no getter for property named &#39;VARCHAR&#39; in
  19. 十三、springboot (八)Admin
  20. psd页面切割成html技巧总结

热门文章

  1. 【EXP/IMP】问题总结
  2. os.walk() 遍历目录下的文件夹和文件
  3. 如何在windows开机画面里隐藏用户
  4. 06--Docker自定义镜像Tomcat9
  5. 卷积神经网络学习笔记——SENet
  6. HTML基础复习3
  7. CMU数据库(15-445)实验2-b+树索引实现(上)
  8. linux搭建ARM可调式环境
  9. 计算机网络安全 —— C# 使用谷歌身份验证器(Google Authenticator)(五)
  10. Redis二进制安全