您的位置:首页 > 其它

CF455B - A Lot of Games(Trie树+博弈)

2014-08-17 22:01 190 查看
B. 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).

题意:

给你很多个单词,两个人轮流在空串后面添加一个字母,并且要一直保证这个串是给出单词的前缀,不能添加一方的的为输。进行k次这个游戏,并且上次游戏输的一方下次游戏先手,问最后一局谁赢。

分析:

首先,要把所有的单词建立 Trie树。

分析单局先手的可能情况:能赢、能输、既能赢也能输(自己能够控制输赢)、不能控制输赢。

对于进行k次游戏,那么要想获胜只有两种可能:

1.在先手能赢能输的情况下,先手一直输一直保持先手,最后一局赢。

2.在先手能赢得情况下,赢一局输一局,奇数局能赢。

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#define INF 0x7fffffff
using namespace std;

const int MAX = 300000 + 10;
int ch[MAX][26], win[MAX], lose[MAX];
int tot = 1;
char s[MAX];

void insert(char *s)
{
    int len = strlen(s);
    int v = 0;
    for(int i = 0; i < len; i++)
    {
        int x = s[i]-'a';
        if(!ch[v][x])
            ch[v][x] = tot++;
        v = ch[v][x];
    }
}
void dfs(int v)
{
    int cnt = 0;
    for (int i = 0; i < 26; i++)
    {
        int u = ch[v][i];
        if (u != 0)
        {
            cnt++;
            dfs(u);
            win[v] |= !win[u];
            lose[v] |= !lose[u];
        }
    }
    if (!cnt)
        lose[v] = true;
}
int main()
{
    int t, k;
    cin>>t>>k;
    while(t--)
    {
        cin>>s;
        insert(s);
    }
    dfs(0);
    if (win[0] && lose[0])
        cout << "First" << endl;
    else if (win[0] && !lose[0])
        cout << ((k & 1) ? "First" : "Second");
    else 
        cout << "Second" << endl;
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: