Triangle War POJ - 1085 极小极大搜索
参考链接: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 }
Triangle War POJ - 1085 极小极大搜索的更多相关文章
- poj 1085 Triangle War 博弈论+记忆化搜索
思路:总共有18条边,9个三角形. 极大极小化搜索+剪枝比较慢,所以用记忆化搜索!! 用state存放当前的加边后的状态,并判断是否构成三角形,找出最优解. 代码如下: #include<ios ...
- poj 1085 Triangle War (状压+记忆化搜索)
Triangle War Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2685 Accepted: 1061 Desc ...
- 极小极大搜索方法、负值最大算法和Alpha-Beta搜索方法
1. 极小极大搜索方法 一般应用在博弈搜索中,比如:围棋,五子棋,象棋等.结果有三种可能:胜利.失败和平局.暴力搜索,如果想通过暴力搜索,把最终的结果得到的话,搜索树的深度太大了,机器不能满足, ...
- POJ 1568 极大极小搜索 + alpha-beta剪枝
极小极大搜索 的个人理解(alpha-beta剪枝) 主要算法依据就是根据极大极小搜索实现的. 苦逼的是,查了两个晚上的错,原来最终是判断函数写错了..瞬间吐血! ps. 据说加一句 if sum & ...
- 极小极大搜索 的个人理解(alpha-beta剪枝)
极小极大搜索的算法过程: 参考文档:http://www.xqbase.com/computer/search_minimax.htm (经典) 主要思想比较简单,但说清楚也不大容易.其核心思想是通过 ...
- 转:极小极大搜索方法、负值最大算法和Alpha-Beta搜索方法
转自:极小极大搜索方法.负值最大算法和Alpha-Beta搜索方法 1. 极小极大搜索方法 一般应用在博弈搜索中,比如:围棋,五子棋,象棋等.结果有三种可能:胜利.失败和平局.暴力搜索,如果想通 ...
- 【poj1085】 Triangle War
http://poj.org/problem?id=1085 (题目链接) 题意 A,B两人玩游戏,在一个大三角形上放火柴,若A放上一根火柴后成功组成一个三角形,那么这个三角形就归属于A,并且A被奖励 ...
- poj 3628 (搜索or背包)
好久没看背包题目了!!!生疏了!!!! 这题是背包题!!!不过对于这题,解决方法还是搜索省时!!! 题意:第一行给你一个N和VV,接下来N行,每行一个数,求得是任选N个数组合求和,求组合的和大于VV而 ...
- POJ 2046 Gap 搜索- 状态压缩
题目地址: http://poj.org/problem?id=2046 一道搜索状态压缩的题目,关键是怎样hash. AC代码: #include <iostream> #include ...
随机推荐
- 【System】paging和swaping之间的区别是什么?
分析paging和swapping的区别,首先要了解内存管理 当虚拟内存用二级存储(物理磁盘)作为主存的扩展时,内核会尽力保持最活跃的数据在主存中.有一下两个内核例程做这件事情: 1.交换(swapp ...
- 【Oracle】等待事件之 V$SESSION_WAIT
(1)-V$SESSION_WAIT 这是一个寻找性能瓶颈的关键视图.它提供了任何情况下session在数据库中当前正在等待什么(如果session当前什么也没在做,则显示它最后的等待事件).当系统存 ...
- 【Oracle】修改列的大小
alter table 表名 modify column_name varchar2(32) alter table 表名 modify (column_name1 varchar(20) defa ...
- 【ORACLE错误】SP2-0618: Cannot find the Session Identifier. Check PLUSTRACE role is enabled
执行set autotrace traceonly的时候,报错 SQL> set autotrace traceonly SP2-0618: Cannot find the Session Id ...
- 腾讯云COS对象存储占据数据容灾C位
说到公有云容灾,大家首先想到的是云上数据备份. 然而,随着企业核心业务逐渐从线下迁移到云上,客户提出了更高的要求.如何确保云上业务的高可用.数据的高可靠,这对云厂商提出了新的挑战. 腾讯云作为全球领先 ...
- 小白的经典CNN复现(二):LeNet-5
小白的经典CNN复现(二):LeNet-5 各位看官大人久等啦!我胡汉三又回来辣(不是 最近因为到期末考试周,再加上老板临时给安排了个任务,其实LeNet-5的复现工作早都搞定了,结果没时间写这个博客 ...
- C++ 中assert断言函数的基本用法
在我们的实际开发过程之中,常常会出现一些隐藏得很深的BUG,或者是一些概率性发生的BUG,通常这些BUG在我们调试的过程中不会出现很明显的问题,但是如果我们将其发布,在用户的各种运行环境下,这些程序可 ...
- (10)-Python3之--引入
1.什么是模块 .py文件就是模块 模块名有命名要求: 1.不要以数字.下划线开头.特殊符号.也不要以中文开头. 2.通常来说,都是以字母开头. 3.不要以关键字来命名.内置函数.内置模块.不要以第三 ...
- Intellij idea 报错:Error : java 不支持发行版本5
保证下面几个地方编译版本一致: 分两步: 第一步,进入Project Structure中设置Project JDK 以及Project Level ,高于JDK5版本 第二步,进入设置中将项目的JD ...
- Linux网络数据包的揭秘以及常见的调优方式总结
https://mp.weixin.qq.com/s/boRWlx1R7TX0NLuI2sZBfQ 作为业务 SRE,我们所运维的业务,常常以 Linux+TCP/UDP daemon 的形式对外提供 ...