【问题描述】

hy 抄题解又被老师抓住了,现在老师把他叫到了办公室。 老师要 hy 和他玩一个游

戏。如果 hy 输了,老师就要把他开除信息组;

游戏分为 k 轮。在游戏开始之前,老师会将 n 个由英文字母组成的字符串放入箱子。

每局开始,字符串为空串,然后两人轮流在末尾追加字符,保证新的字符串为箱子中某

字符串的前缀,直到有一个人不能操作,不能操作的那个人就输掉当前的一轮。新一轮

由上一句输的人先手。最后一局赢的人获胜。

假定老师和 hy 都能采取最优的策略,且老师为了彰显自己的大度让 hy 先手,求 hy 能否

获胜。

【输入格式】

输入包括多组数据,输入以文字流结尾(EOF)为结束。

每组数据的第一行包含两个整数 n, k,分别表示放入箱子字符串的数量和游戏的轮

数。

接下来 n 行,每行一个字符串表示由英文字母组成的句子。

【输出格式】

每组数据第一行,输出 hy 是否能赢,若能赢输出”HY wins!“,否则输出”Teacher

wins!”。

【样例输入 1】

2 3

a

b

3 1

a

b

c

【样例输出 1】

HY wins!

HY wins!

【样例输入 2】

1 2

ab

【样例输出 2】

Teacher wins!【评测用例规模与约定】

对于 40%的评测用例,1≤n≤10,1≤k≤10 4 ;

对于 100%的评测用例,1≤n≤10 5 ,1≤k≤10 9 ,保证所有字符串总长度不超过 10 5 ,数据组

数不超过 10

Solution

先把所有的字符串插入 Trie 树,然后就是博弈论了。

博弈论分为三种情况:

1.若先手无必胜策略即先手必败则先手一直先手,最后一局后手胜;

2.若先手有必胜策略则下一局成后手,即为胜败交替,此时,最后一句的胜败决定于 k 的奇

偶性;

3.先手有必胜策略有必败策略,则先手前 k-1 局败,最后一局先手胜。

考虑 \(dp\) 转移 ,\(f[i]\) 代表当前节点是否能肯定赢,\(F[i]\) 代表当前节点是否能肯定输。

  • 对于深度为偶数的节点,那么只要子节点中有任意一个满足,即可使当前 \(f[x]\) 或者 \(F[x]\) 为 \(1\) 。

    因为此时为 HY 做决定的时间。
  • 对于深度为奇数的节点,即此时由 Teacher 做决定,那么此时只有当其所有子节点都为肯定输或者肯定赢是才能计数。

然后按部就班转移即可。

Code

#include<bits/stdc++.h>
#define N 100001
#define ll long long
using namespace std; int ch[N][26],cnt;
void insert(string s)
{
int u=0,n=s.length();
for(int i=0;i<n;i++)
{
if(!ch[u][s[i]-'a'])
ch[u][s[i]-'a']=++cnt;
u=ch[u][s[i]-'a'];
} return;
} int pd[N],Pd[N],sum[N];
void dfs(int x,int dep,int zm)
{
sum[x]=1;
for(int i=0;i<26;i++)
if(ch[x][i])
{
dfs(ch[x][i],dep+1,i);
sum[x]+=sum[ch[x][i]];
}
if(sum[x]==1)
{
if(dep%2==1)pd[x]=1;
else Pd[x]=1;
return;
}
if(dep%2!=1)
{
for(int i=0;i<26;i++)
if(ch[x][i])
{
pd[x]=max(pd[x],pd[ch[x][i]]);
Pd[x]=max(Pd[x],Pd[ch[x][i]]);
}
}else
{
int pp=1,qq=1;
for(int i=0;i<26;i++)
if(ch[x][i])
{
if(!pd[ch[x][i]])pp=0;
if(!Pd[ch[x][i]])qq=0;
}pd[x]=pp,Pd[x]=qq;
}
return;
} int n,k;
int main()
{
freopen("amerce.in","r",stdin);
freopen("amerce.out","w",stdout);
while(scanf("%d",&n)!=EOF)
{
memset(pd,0,sizeof(pd));
memset(Pd,0,sizeof(Pd));
memset(sum,0,sizeof(sum));
memset(ch,0,sizeof(ch));
scanf("%d",&k); cnt=0;
for(int i=1;i<=n;i++)
{
string s;
cin>>s; insert(s);
}
dfs(0,0,0);
if(pd[0]!=1){cout<<"Teacher wins!"<<endl;continue;}
if(pd[0]==1&&Pd[0]==0)
{
if(k%2==1)cout<<"HY wins!"<<endl;
else cout<<"Teacher wins!"<<endl;
continue;
}
if(pd[0]==1&&Pd[0]==1)
cout<<"HY wins!"<<endl;
}
return 0;
}

HY 的惩罚 (Trie 树,博弈论)的更多相关文章

  1. SPOJ11414 COT3 博弈论 + Trie树合并

    考虑对于每个子树从下往上依次考虑 对于叶子节点而言,如果可以染色,那么其\(sg\)值为\(1\),否则为\(0\) 考虑往上合并 如果选择了\(x\),那么后继状态就是其所有子树 如果选了其他子树中 ...

  2. 数据结构 | 30行代码,手把手带你实现Trie树

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法和数据结构专题的第28篇文章,我们一起来聊聊一个经典的字符串处理数据结构--Trie. 在之前的4篇文章当中我们介绍了关于博弈论的 ...

  3. 基于trie树做一个ac自动机

    基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...

  4. 基于trie树的具有联想功能的文本编辑器

    之前的软件设计与开发实践课程中,自己构思的大作业题目.做的具有核心功能,但是还欠缺边边角角的小功能和持久化数据结构,先放出来,有机会一点点改.github:https://github.com/chu ...

  5. hihocoder-1014 Trie树

    hihocoder 1014 : Trie树 link: https://hihocoder.com/problemset/problem/1014 题意: 实现Trie树,实现对单词的快速统计. # ...

  6. 洛谷P2412 查单词 [trie树 RMQ]

    题目背景 滚粗了的HansBug在收拾旧英语书,然而他发现了什么奇妙的东西. 题目描述 udp2.T3如果遇到相同的字符串,输出后面的 蒟蒻HansBug在一本英语书里面找到了一个单词表,包含N个单词 ...

  7. 通过trie树实现单词自动补全

    /** * 实现单词补全功能 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #incl ...

  8. #1014 Trie树

    本题主要是求构造一棵Trie树,即词典树用于统计单词. C#代码如下: using System; using System.Collections.Generic; using System.Lin ...

  9. Trie树-字典查找

    描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题: ...

随机推荐

  1. 接口自动化之提取响应结果(raw、json)

    做接口测试时,我们一般会取得响应结果的部分值,来与预期结果对比,做断言 目录 1.响应结果类型 2.json响应结果的提取 3.raw响应结果的提取 1.响应结果类型 通过fiddler的respon ...

  2. Android Bitmap变迁与原理解析(4.x-8.x)

    App开发不可避免的要和图片打交道,由于其占用内存非常大,管理不当很容易导致内存不足,最后OOM,图片的背后其实是Bitmap,它是Android中最能吃内存的对象之一,也是很多OOM的元凶,不过,在 ...

  3. js-禁止长页面滚动

    标题的需求问题其实我经常遇到.尤其是在碰到页面同时出现有视频及弹层的情况. 当然我说的问题皆是针对微信H5开发的哈 IOS中,视频播放,弹层出现时,视频在弹层的下面,不会出现问题: 安卓手机中,完了, ...

  4. Vue --》 如何在vue中调用百度地图

    1.项目根目录下下载百度地图插件 npm install vue-baidu-map –save 2.在首页index.html中引入百度地图: <script type="text/ ...

  5. 一次特殊的“VARCHAR转numeric失败”错误记录

    今天接触到一个很有意思的问题.当我在执行一条INSERT的sql语句时,他总是报字符串转数字类型失败. 问题 首先,该表中的所有数字类型的字段都是非必填,其次,每个数字类型的字段都有默认值.最令我感到 ...

  6. MySQL-第十二篇管理结果集

    1.ResultSet 2.可更新的结果集,使用ResultSet的updateRow()方法.

  7. Monitor HDU6514 二维差分入门学习

    Monitor HDU 6514 二维差分入门学习 题意 小腾有\(n*m\)的田地,但是有小偷来偷东西,在一片矩形区域上,有一部分区域是监控可以覆盖到的,这部分区域由一个或多个包含于该矩形区域的小矩 ...

  8. Excel VBA批量处理寸照名字(类模块加FSO版)

    需求:因为处理学生学籍照片,从照相馆拿回来的寸照是按班级整理好,文件名是相机编号的文件.那么处理的话,是这么一个思路,通过Excel表格打印出各班A4照片列表,让学生自行填上照片对应姓名.表格收回来后 ...

  9. springboot多数据源&动态数据源(主从)

    多数据源 使用Spring Boot时,默认情况下,配置DataSource非常容易.Spring Boot会自动为我们配置好一个DataSource. 如果在application.yml中指定了s ...

  10. JVM(19)之 Class文件常量池

    开发十年,就只剩下这套架构体系了! >>>   在上一博文Class文件中,我们了解了Class文件的一些基础知识.他的整个内部结构就是一张很大的表,我们就是从这张表入手,一一分析每 ...