CodeForces 455B A Lot of Games (博弈论)
A Lot of Games
题目链接:
http://acm.hust.edu.cn/vjudge/contest/121334#problem/J
Description
Andrew, Fedor and Alex are inventive guys. Now they invent the game with strings for two players.
Given a group of n non-empty strings. During the game two players build the word together, initially the word is empty. The players move in turns. On his step player must add a single letter in the end of the word, the resulting word must be prefix of at least one string from the group. A player loses if he cannot move.
Andrew and Alex decided to play this game k times. The player who is the loser of the i-th game makes the first move in the (i + 1)-th game. Guys decided that the winner of all games is the player who wins the last (k-th) game. Andrew and Alex already started the game. Fedor wants to know who wins the game if both players will play optimally. Help him.
Input
The first line contains two integers, n and k (1 ≤ n ≤ 105; 1 ≤ k ≤ 109).
Each of the next n lines contains a single non-empty string from the given group. The total length of all strings from the group doesn't exceed 105. Each string of the group consists only of lowercase English letters.
Output
If the player who moves first wins, print "First", otherwise print "Second" (without the quotes).
Sample Input
Input
2 3
a
b
Output
First
Input
3 1
a
b
c
Output
First
Input
1 2
ab
Output
Second
##题意:
给出n个字符串(总长度不超过10^5);
A B两人轮流进行如下操作:
1. 初始时目标串为空
2. 当前玩家在目标串末尾添加一个字符
3. 要求每次添加后的目标串是给出的任一字符串的前缀
4. 不能操作者输
(游戏共进行k轮,每轮输者在下一轮为先手)
##题解:
首先这是一个博弈论问题.
要求每次目标串都是给定串的前缀,很自然想到用字典树来建模.
这个游戏有一个特别的地方:本局的赢家在下局是后手. 这意味着玩家可能会选择输掉当前局来获取最后的胜利.
我们只用处理单局的情况:
1. 如果先手在单局中处于必输状态,那么他一定会输掉最后的比赛(一直输).
2. 如果先手在单局中有必胜的走法,那么他不一定会选择在所有情况下都赢.
1. 如果先手可以控制自己必输或必赢,那么他一定会赢得最后的比赛(一直输,最后一场选择胜利).
2. 如果先手只能赢无法输(比如只有一个字符),那么他的结果取决与k的奇偶性(奇胜偶败).
- 综上,只需要处理出单局中先手是必输/必胜/可输可赢,这里采用两次dfs来完成判断:
- 先搜索是否有必胜的走法(叶结点必输,可到必输的点为必胜,只能到必胜的点为必输).
- 再搜索是否有必败的走法(叶结点必输,可到必胜的点为必输,只能到必输的点为必胜).
##代码:
``` cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define eps 1e-8
#define maxn 101000
#define mod 100000007
#define inf 0x3f3f3f3f
#define IN freopen("in.txt","r",stdin);
using namespace std;
struct Trie
{
bool isStr;
int next;
Trie(){isStr=false;next=-1;}
}trie[maxn][26];
int cnt;
void insert(char s)
{
int len=strlen(s),cur=0;
for(int i=0;i<len;i++)
{
if(trie[cur][s[i]-'a'].next==-1)
trie[cur][s[i]-'a'].next=++cnt; / from 1; 0 is root /
if(i==len-1)
trie[cur][s[i]-'a'].isStr=true;
cur=trie[cur][s[i]-'a'].next;
}
}
/以上为字典树模版*/
int n,m;
char str[maxn];
/*
1表示当前局面存在必胜走法; 0表示只有必败.
子节点中有0则1,全1则0.
*/
int dfs(int cur) {
int ans = 0;
int cnt = 0;
for(int i=0; i<26; i++) {
if(trie[cur][i].next != -1)
cnt+=1, ans += dfs(trie[cur][i].next);
}
if(cnt == ans) return 0;
else return 1;
}
/*
1表示当前局面存在必输走法; 0表示只有必赢.
子节点中有0则1,全1则0.
*/
int dfs2(int cur) {
int ans = 0;
int cnt = 0;
for(int i=0; i<26; i++) {
if(trie[cur][i].next != -1)
cnt+=1, ans += dfs2(trie[cur][i].next);
}
if(!cnt) return 1;
if(cnt == ans) return 0;
else return 1;
}
void init() {
for(int i=0; i<maxn; i++) {
for(int j=0; j<26; j++) {
trie[i][j].isStr = 0;
trie[i][j].next = -1;
}
}
}
int main(int argc, char const *argv[])
{
//IN;
while(scanf("%d %d", &n,&m) != EOF)
{
init();
while(n--) {
scanf("%s", str);
insert(str);
}
int ans1 = dfs(0);
if(!ans1) {
puts("Second"); continue;
}
int ans2 = dfs2(0);
if(!ans2) {
if(m&1) puts("First");
else puts("Second");
} else {
puts("First");
}
}
return 0;
}
CodeForces 455B A Lot of Games (博弈论)的更多相关文章
- Codeforces 455B A Lot of Games(字典树+博弈)
题目连接: Codeforces 455B A Lot of Games 题目大意:给定n.表示字符串集合. 给定k,表示进行了k次游戏,然后是n个字符串.每局開始.字符串为空串,然后两人轮流在末尾追 ...
- Codeforces 455B A Lot of Games
http://codeforces.com/contest/455/problem/B 题目大意: 给出n个字符串,进行k次游戏,每次游戏输家下次作为先手,游戏规则为每次放一个字母,导致当前构造的字符 ...
- Codeforces 455B A Lot of Games:博弈dp【多局游戏】
题目链接:http://codeforces.com/problemset/problem/455/B 题意: 给你n个字符串,然后进行k局游戏. 每局游戏开始有一个空串,然后双方轮流给这个串的末尾添 ...
- codeforces 455B A Lot of Games(博弈,字典树)
题目 参考自博客:http://blog.csdn.net/keshuai19940722/article/details/38455269 //字典树,博弈 根据当前节点的后续来确定当前节点的状态, ...
- Codeforces 455B A Lot of Games 字典树上博弈
题目链接:点击打开链接 题意: 给定n个字符串,k局游戏 对于每局游戏,2个玩家轮流给一个空串加入一个小写字母使得加完后的字符串不是n个字符串的前缀. 输家下一轮先手 问是先手必胜还是后手必胜 思路: ...
- [codeforces 325]B. Stadium and Games
[codeforces 325]B. Stadium and Games 试题描述 Daniel is organizing a football tournament. He has come up ...
- Codeforces 980 E. The Number Games
\(>Codeforces \space 980 E. The Number Games<\) 题目大意 : 有一棵点数为 \(n\) 的数,第 \(i\) 个点的点权是 \(2^i\) ...
- codeforces 1451D,一道有趣的博弈论问题
大家好,欢迎来到codeforces专题. 今天选择的问题是Contest 1451场的D题,这是一道有趣简单的伪博弈论问题,全场通过的人有3203人.难度不太高,依旧以思维为主,坑不多,非常友好. ...
- Codeforces 549C. The Game Of Parity[博弈论]
C. The Game Of Parity time limit per test 1 second memory limit per test 256 megabytes input standar ...
随机推荐
- NFC(2)NFC、蓝牙和红外之间的差异
NFC(2)NFC.蓝牙和红外之间的差异表
- js 返回的数据类型 5类
对变量或值调用 typeof 运算符将返回下列值之一: undefined - 如果变量是 Undefined 类型的 boolean - 如果变量是 Boolean 类型的 number - 如果变 ...
- Topcoder SRM 630 (500 floyed 暴力 _builtin_popcount())
题意:给n个点,保证图联通,给点相连的距离,求一个最多的点,这些点之间的距离都是相同的. 分析: 下面的代码是我们房间第一的大神的,写的很简洁,我的思路和他的一样,但是我不知道错哪了. 思路是暴力枚举 ...
- LA 3029 - City Game (简单扫描线)
题目链接 题意:给一个m*n的矩阵, 其中一些格子是空地(F), 其他是障碍(R).找一个全部由F 组成的面积最大的子矩阵, 输出其面积乘以3的结果. 思路:如果用枚举的方法,时间复杂度是O(m^2 ...
- poj 2948 Martian Mining (dp)
题目链接 完全自己想的,做了3个小时,刚开始一点思路没有,硬想了这么长时间,想了一个思路, 又修改了一下,提交本来没抱多大希望 居然1A了,感觉好激动..很高兴dp又有所长进. 题意: 一个row*c ...
- PL/SQL Developer自动补全SQL技巧
s = SELECT t.* FROM t w = WHERE b = BETWEEN AND l = LIKE '%%' o = ORDER BY insw = IN (SELECT a FROM ...
- hdu 4617 Weapon(叉积)
大一学弟表示刚学过高数,轻松无压力. 我等学长情何以堪= = 求空间无限延伸的两个圆柱体是否相交,其实就是叉积搞一搞 详细点就是求两圆心的向量在两直线(圆心所在的直线)叉积上的投影 代码略挫,看他的吧 ...
- linux - markdown编辑器
1. linux可以用web-qq,http://web2.qq.com,[我们从未放弃成长,这句话挺感动我的.] (禽兽!你怎么在一开始就跑题!?) ————我只要“及时预览”———— 2. htt ...
- 【轻院热身赛】级数求和、进制转换、candy
[题目链接:级数求和] Problem A: 级数求和 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 409 Solved: 240 SubmitSt ...
- Java-泛型编程-使用通配符? extends 和 ? super
原文地址:http://blog.csdn.net/fw0124/article/details/42296283 泛型中使用通配符有两种形式:子类型限定<? extends xxx>和超 ...