您的位置:首页 > 其它

Codeforces Round #260(Div2) Problem D. A Lot of Games

2014-08-09 14:57 369 查看
D. A Lot of Games

time limit per test
1 second

memory limit per test
256 megabytes

input
standard input

output
standard output

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).

题解:博弈题,比赛的时候连跪两发,赛后经提醒才发现坑点,真是脑洞太小啊T_T

很明显可以发现每一个子游戏是基本独立的,那么只要搞清楚每一个子游戏的先手会赢还是输,最后将K个子游戏合并就可以知道最后的状态了。子游戏的状态可以在Trie上进行SG值判定得到。

一开始的想法是,每个子游戏的状态是两种:1.先手必胜2.先手必败,后来朱神说,要是赢了一个子游戏会导致输掉整个游戏,那先手也可以选择输掉这个子游戏。

所以这样的话一个子游戏的状态可以分为四种

1.先手可以选择赢,也可以选择输。这样整个游戏胜者毕为先手。

2.先手只能赢。这样整个游戏胜者随K不断交替。

3.先手只能输。这样整个游戏胜者毕为后手。

4.先手不能选择自己的胜负。这样整个游戏胜者毕为后手。

分析完毕,挫代码献上

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <stack>
using namespace std;
#define LL long long
#define MOD 1000000007

struct Trie
{
int next[100100][26];
bool end[100100];
bool sg[100100],anti_sg[100100];
int root,L;
int newnode()
{
for(int i = 0;i < 26;i++)
next[L][i] = -1;
L++;
end[L-1]=true;
sg[L-1]=0;
anti_sg[L-1]=0;
return L-1;
}
void init()
{
L = 0;
root = newnode();
}
void search(int now)
{
if (end[now])
{
sg[now]=0;
anti_sg[now]=1;
return ;
}
for (int i=0;i<26;i++)
{
if (next[now][i]!=-1)
{
search(next[now][i]);
if (sg[next[now][i]]==0) sg[now]=1;
if (anti_sg[next[now][i]]==0) anti_sg[now]=1;
}
}
}
void insert(char buf[])
{
int len = strlen(buf);
int now = root;
for(int i = 0;i < len;i++)
{
if(next[now][buf[i]-'a'] == -1)
next[now][buf[i]-'a'] = newnode();
if (end[now]) end[now]=false;
//cout<<now<<' '<<end
995f
[now]<<endl;
now = next[now][buf[i]-'a'];
//cout<<now<<' '<<buf[i]<<endl;
}
}
int query()
{
search(0);
if (sg[0]==1&&anti_sg[0]==1) return 1;
if (sg[0]==1&&anti_sg[0]==0) return 2;
if (sg[0]==0&&anti_sg[0]==1) return 3;
if (sg[0]==0&&anti_sg[0]==0) return 4;
}
};
Trie AC;
char ch[100100];

int main()
{
int n,k,a;
while(~scanf("%d%d",&n,&k))
{
getchar();
AC.init();
for (a=1;a<=n;a++)
{
scanf("%s",ch);
AC.insert(ch);
}
int flag=AC.query();
//cout<<flag<<endl;
if (flag==1)
{
printf("First\n");
}
else
if (flag==2)
{
if (k%2==1) printf("First\n");
else printf("Second\n");
}
else
printf("Second\n");

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces 游戏