多边形游戏(博弈)
来源:互联网 发布:中建上海设计院 知乎 编辑:程序博客网 时间:2024/05/17 09:05
问题描述:
多边形游戏是一个双人游戏。游戏在一个有n个顶点的凸多边形上进行,这个凸多边形的n-3条对角线将多边形分成n-2个三角形,三角形中的一个被染成黑色,其余是白色。双方轮流进行游戏,当轮到一方时,他必须沿着画好的对角线,从多边形上切下一个三角形。切下黑色三角形的一方获胜。
输入
多组测试数据。每组测试数据第一行n,表示顶点数。多边形的顶点从0到n-1顺时针标号,接着的n-2行描述组成多边形的三角形,且第一行给出的是黑色三角形的描述。当n=0时表示输入结束。
输出
对每组测试数据,输出YES或NO:YES,表示先走的一方有必胜策略;NO,表示先走的一方没有必胜策略。
样例
1
6
0 1 2
2 4 3
4 2 0
0 5 4
YES
思路:本题初看似乎很复杂,设计那么多的边和三角形,但想想,可以将图形进行转换,尝试将多边形的每个三角形看成一个结点,有公共边的三角形所对应的顶点之间连一条边,则所给的图形可以看作是有n-2个结点,n-3条边的一个无向图G。显然,G构成一棵树T,把黑色三角形对应的结点看作树T的根,则树T最多有三棵子树。
接下来考虑必胜策略,显然,若要切掉根结点,则必须先将根的子树切到只剩一根。需要考虑的只是子树的结点个数,用非负整数(x,y,z)表示根的三棵子树的结点个数,不妨设x<=y<=z,则显然z>0。
(1)y=0,则x=0,为必胜状态;
(2)y>0,则最终结局必是(1,0,0),(0,1,0),(0,0,1)的一种;
显然,在(2)情况下,要想让先走的赢,x+y+z为奇数。
算法实现:主要的问题在于x,y,z的求取。由于多边形为顺时针编号,设黑三角形的编号为(i,j,k),假设满足i<j<k,则树T的三棵子树对应的多边形分别有j-i-1,k-j-1,n-(k-i-1)个顶点,也就会包含有j-i-1,k-j-1,n+i-k-1个三角形(结点),排序后,对应x,y,z。
代码:
int main(){ while(cin>>n&&n) { cin>>i>>j>>k; n-=3; while(n--) cin>>a>>b>>c; Swap(i,j,k);//排序:i<j<k x=j-i-1,y=k-j-1,z=n+i-k-1; Swap(x,y,z);//排序:x<=y<=z if(y==0||(x+y+z)&1) printf("Yes\n"); else printf("No\n"); }}
- 多边形游戏(博弈)
- 多边形游戏(C++)
- [BZOJ2927][Poi1999]多边形之战(博弈)
- 组合游戏(博弈)
- 盒子游戏(博弈)
- 多边形游戏(POJ 1179)
- 多边形游戏(动态规划)
- 多边形游戏
- 多边形游戏
- 多边形游戏
- 多边形游戏
- 多边形游戏
- 多边形游戏
- 多边形游戏
- 多边形游戏
- 多边形游戏
- 取石子游戏(博弈)
- [POJ2975]Nim游戏(博弈)
- 最大子数组问题
- PDF电子书生成目录的快捷方法!!!
- git撤销已经push到远程的commit
- 网易2017内推 [编程题]堆棋子@Java
- 安装beego (windows 版)
- 多边形游戏(博弈)
- HDUOJ 1863 畅通工程(kruskal)
- 银行转账业务-使用事务
- C语言中的atan 与atan2
- 小型游戏《笑傲江湖之精忠报国》全过程_03
- 51nod 1267 4个数和为0(二分)
- linux下如何安装jdk
- DeepLearning&Keras学习笔记3__mnist数据集CNN
- 一款有趣的游戏