传送门

UPD:之前可能对白色变无色的过程讲的不是很清楚,已经补充


显然在双方绝顶聪明的情况下,黑色不可能赢

首先考虑树上一个白色的点都没有的情况:

1、如果树上有一个点的度数\(\geq 4\),白色必赢,只需要第一次将这一个点染成白色,接着随便染它的两个邻居就可以达成目标

2、如果树上有一个点的度数\(=3\),且它所连的\(3\)个点之间至少有\(2\)个点不是叶子节点,白色必赢,只需要第一次染这一个点,第二次染它的一个非叶子邻居,第三次就一定至少存在一个未被染色的点与这两个相邻。

那么剩下的情况,树的形态只会是下图中的三种

但是还没完(我以为到这里就完了结果WA2被Tutorial点名)

最重要的3、如果树的形态是上面的图中最下面的那一种,而且总点数为奇数,那么白色必赢

图长下面这样,中间的……省略的是一条链,编号从左往右递增。

白色最开始染\(2\)号点,黑色如果染\(3\)号点白色直接染\(1\)号点,所以黑色必须染\(1\)号点。此时白色染\(4\)号点,黑色又只能染\(3\)号点……如是白色染到\(2N\)号点,黑色染\(2N-1\)号点之后,白色染\(2N+1\)号点,那么最右边就会有两个未被染的点,白色就赢了

其余的情况显然都是Draw的

然后考虑已经被染成白色的点的影响,最开始天真的我想直接各种特判过掉,结果WA14不晓得怎么回事

我们已经考虑了树上没有被染成白色的点的所有情况,那么能否将一个已经被染成白色的点等价为若干未被染成白色的点?实际上是可以的

假设下图中\(1\)号点在原树上是一个白色点,那就在保留它原来的邻居的基础上给它额外连上\(3\)个点,连成下面的\(ABCD\)结构

原图\(1\)号点对应新图的\(A\)号点,原图上\(1\)号点跟哪些点连了边,新图上\(A\)号点也和它们连边,然后在下面挂上\(BCD\)三个点

对于执白色的人来说,如果TA在某一回合涂白了\(A\)号点,这个时候如果执黑色者不涂黑\(B\)号点,那么执白色者将会在下一回合涂白\(B\)号点,对于\(CD\)两个点,白色就一定可以涂白其中一个,白色就赢了

所以执黑色者只能涂黑\(B\)号点。而这个时候\(BCD\)三个点对于胜负已经没有影响了,可以直接砍掉这三个点,就相当于白色直接涂白了\(A\)号点,也就是涂白了原图的\(1\)号点,然后又来到白色的回合。

  1. #include<bits/stdc++.h>
  2. //This code is written by Itst
  3. using namespace std;
  4. inline int read(){
  5. int a = 0;
  6. char c = getchar();
  7. bool f = 0;
  8. while(!isdigit(c)){
  9. if(c == '-')
  10. f = 1;
  11. c = getchar();
  12. }
  13. while(isdigit(c)){
  14. a = (a << 3) + (a << 1) + (c ^ '0');
  15. c = getchar();
  16. }
  17. return f ? -a : a;
  18. }
  19. const int MAXN = 1e6 + 9;
  20. struct Edge{
  21. int end , upEd;
  22. }Ed[MAXN << 1];
  23. int head[MAXN] , in[MAXN] , N , cntEd , cnt;
  24. char s[MAXN];
  25. inline void addEd(int a , int b){
  26. Ed[++cntEd].end = b;
  27. Ed[cntEd].upEd = head[a];
  28. head[a] = cntEd;
  29. ++in[a];
  30. }
  31. int main(){
  32. for(int T = read() ; T ; --T){
  33. N = read();
  34. cntEd = 0;
  35. memset(head , 0 , sizeof(int) * (N + 1));
  36. memset(in , 0 , sizeof(int) * (N + 1));
  37. for(int i = 1 ; i < N ; ++i){
  38. int a = read() , b = read();
  39. addEd(a , b);
  40. addEd(b , a);
  41. }
  42. scanf("%s" , s + 1);
  43. if(N < 3){
  44. puts("Draw");
  45. continue;
  46. }
  47. if(N == 3){
  48. int cnt = 0;
  49. for(int i = 1 ; i <= N ; ++i)
  50. cnt += s[i] == 'W';
  51. puts(cnt >= 2 ? "White" : "Draw");
  52. continue;
  53. }
  54. bool ifans = 0;
  55. int cnt1 = 0;
  56. for(int i = 1 ; i <= N ; ++i)
  57. if(s[i] == 'W'){
  58. addEd(i , ++N);
  59. head[N] = 0;
  60. addEd(N , i);
  61. in[N] = 3;
  62. }
  63. for(int i = 1 ; !ifans && i <= N ; ++i)
  64. if(in[i] > 3)
  65. ifans = 1;
  66. else
  67. if(in[i] == 3){
  68. int cnt = 0;
  69. for(int j = head[i] ; j ; j = Ed[j].upEd)
  70. cnt += in[Ed[j].end] >= 2;
  71. ifans = cnt >= 2;
  72. ++cnt1;
  73. }
  74. if(cnt1 == 2 && (N & 1))
  75. ifans = 1;
  76. puts(ifans ? "White" : "Draw");
  77. }
  78. return 0;
  79. }

CF1110G Tree-Tac-Toe 博弈论、构造的更多相关文章

  1. Principle of Computing (Python)学习笔记(7) DFS Search + Tic Tac Toe use MiniMax Stratedy

    1. Trees Tree is a recursive structure. 1.1 math nodes https://class.coursera.org/principlescomputin ...

  2. POJ 2361 Tic Tac Toe

    题目:给定一个3*3的矩阵,是一个井字过三关游戏.开始为X先走,问你这个是不是一个合法的游戏.也就是,现在这种情况,能不能出现.如果有人赢了,那应该立即停止.那么可以知道X的步数和O的步数应该满足x= ...

  3. 【leetcode】1275. Find Winner on a Tic Tac Toe Game

    题目如下: Tic-tac-toe is played by two players A and B on a 3 x 3 grid. Here are the rules of Tic-Tac-To ...

  4. 2019 GDUT Rating Contest III : Problem C. Team Tic Tac Toe

    题面: C. Team Tic Tac Toe Input file: standard input Output file: standard output Time limit: 1 second M ...

  5. CodeForces - 1098.DIV1.C: Construct a tree(贪心,构造)

    Misha walked through the snowy forest and he was so fascinated by the trees to decide to draw his ow ...

  6. Atcoder Regular Contest 117 D - Miracle Tree(分析性质+构造)

    Atcoder 题面传送门 笑死,阴间语文作业到现在还没写完,为了在这个点保持精神,我只好来颓篇题解辣 我们考虑探究一下怎么最小化 \(\max\limits_{i=1}^nE_i\),我们假设 \( ...

  7. [CareerCup] 17.2 Tic Tac Toe 井字棋游戏

    17.2 Design an algorithm to figure out if someone has won a game oftic-tac-toe. 这道题让我们判断玩家是否能赢井字棋游戏, ...

  8. Epic - Tic Tac Toe

    N*N matrix is given with input red or black.You can move horizontally, vertically or diagonally. If ...

  9. python 井字棋(Tic Tac Toe)

    说明 用python实现了井字棋,整个框架是本人自己构思的,自认为比较满意.另外,90%+的代码也是本人逐字逐句敲的. minimax算法还没完全理解,所以参考了这里的代码,并作了修改. 特点 可以选 ...

  10. ACM-Team Tic Tac Toe

    我的代码: #include <bits/stdc++.h> using namespace std; int main() { char a[3][3]; int i,j=0; for( ...

随机推荐

  1. 【读书笔记】iOS-iPad与iPhone

    在开发通用型应用的时候,你总是需要记住,iPad并不是一个大大的iPod touch,为iPad开发的应用的界面应该更好地利用iPad的大屏幕,而不应该是iPhone应用的复制品. 参考资料:< ...

  2. Rxjava学习(二操作符)

    操作符是为了解决对Observable对象的变换的问题,操作符用于在Observable和最终的Subscriber之间修改Observable发出的事件 1.filter filter()操作符是可 ...

  3. (网页)20个JS 小技巧超级实用

    转自CSDN: 1. 将彻底屏蔽鼠标右键 oncontextmenu=”window.event.returnValue=false”< table border oncontextmenu=r ...

  4. Yii1.1.16学习记录

    最近工作中用到Yii框架,为此专门在网上找了些相关教程学一下,尽管教程比较老,但学完后至少对Yii框架有了基本了解,特别是widget的使用,感觉Yii真的很强大. 一.框架介绍与安装 框架源码下载 ...

  5. LeetCode题解之Insert into a Binary Search Tree

    1.题目描述 2.分析 插入算法. 3.代码 TreeNode* insertIntoBST(TreeNode* root, int val) { insert(root, val); return ...

  6. Scala多重继承及AOP

    package traitandclass /** * Created by zhen on 2018/8/23. */ class Human { println("Human" ...

  7. Java获取数据库表 字段 存储的部分数据

    在浏览器页面,选中图片(可多选) >单击删除按钮. 重点是, 本数据库表TabHeBeiTianQi中 存在 同一id,对应的picLocalPath字段  存储了多张图片,图片地址用   逗号 ...

  8. 建立标准编码规则(一)-自定义C#代码分析器

    1.下载Roslyn的Visual Studio分析器模板插件(VS2015 或VS2017) https://marketplace.visualstudio.com/items?itemName= ...

  9. Appium1.9.1 之 Desired Capabilities 释疑

    服务关键字 Desired Capabilities在启动session的时候是必须提供的. Desired Capabilities本质上是以key value字典的方式存放,客户端将这些键值对发给 ...

  10. Vue仿抽屉

    创建VUE项目的步骤: npm install vue-cli -g vue init webpack myproject cd myproject npm run dev 组件:它是可扩展的html ...