Codeforces 455B. A Lot of Games

如果先手没有必胜策略,k为奇数时后手赢,k为偶数时后手可以输第一盘赢第二盘,直至赢最后一盘,不管怎么样都是后手赢。

如果先手有必败策略,同理不管怎么样先手赢。(有必败策略一定有必胜策略吗?)

除此之外, k为奇数是先手赢,k为偶数后手赢。

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 ≤ 1051 ≤ 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 test(s)
input
2 3
a
b
output
First
input
3 1
a
b
c
output
First
input
1 2
ab
output
Second

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define prt(k) cout<<#k"="<<k<<" ";
#define ll long long
const int N=1e5+4;
#include<cmath>
#include<algorithm>
int n;
int ch[N][26],end[N];
int L,root;
int newnode(){ memset(ch[L],-1,sizeof ch[L]);end[L++]=0; return L-1;}
void init() { L=0; root=newnode(); }
void insert(char s[])
{
    int n=strlen(s),u=root;
    for(int i=0;i<n;i++)
    {
        int& tmp=ch[u][s[i]-'a'];
        if(tmp==-1) tmp=newnode();
        u=tmp; end[u]=0;
    }
    end[u]=1;
}
bool dfs(int u)
{
    if(end[u]) return 0;
    for(int i=0;i<26;i++)
    {
        if(ch[u][i]==-1) continue;
        if(!dfs(ch[u][i])) return 1;
    }
    return 0;
}

char s[N];
bool can_win[N];    ///是否有必胜策略
bool can_lose[N];   ///是否有必败策略
int main()
{
    int n,k;
    cin>>n>>k;  init();
    for(int i=0;i<n;i++) {scanf("%s",s); insert(s); }
    bool ok=dfs(root);
    for(int i=L-1;i>=0;i--)
    {
        bool move=0;
        for(int j=0;j<26;j++)
        if(ch[i][j]>0) { move=1; break; }
        if(!move) { can_win[i]=0,can_lose[i]=1;continue;}
        for(int j=0;j<26;j++)
        if(ch[i][j]>0) {
            if(!can_win[ch[i][j]]) can_win[i]=1;
            if(!can_lose[ch[i][j]]) can_lose[i]=1;
        }
    }
    if(!can_win[0]) { puts("Second"); return 0; }
    if(can_lose[0]) { puts("First"); return 0; }
    ///can_win && !can_lose
    printf("%s\n",k%2==1?"First":"Second");
}


你可能感兴趣的:(博弈,codeforces)