字典树+博弈论。
建立字典树,在字典树上dfs,求出根节点能否必胜和必胜。然后根据先手能否必胜和必输的条件进行判断。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=200200;
char s[MAXN];
int cnt,n;
struct Node
{
int flag,win,loss;
int son[26];
}trie[MAXN];
void insert(char *s)
{
for(int l=strlen(s),x=0,i=0;i<l;i++)
{
if(!trie[x].son[s[i]-'a'])
trie[x].son[s[i]-'a']=++cnt;
x=trie[x].son[s[i]-'a'];
if(i==l-1)
trie[x].flag++;
}
}
void dfs(int x)
{
int i,tmp[30],ncanlos=0,canlos=0;
memset(tmp,0,sizeof(tmp));
for(i=0;i<26;i++)
{
if(trie[x].son[i])
{
dfs(trie[x].son[i]);
tmp[trie[trie[x].son[i]].win]++;
if(trie[trie[x].son[i]].loss)
ncanlos++;
else
canlos++;
}
}
if(!ncanlos&&!canlos)
trie[x].loss=1;
else if(canlos)
trie[x].loss=1;
else
trie[x].loss=0;
for(i=0;i<=26;i++)
{
if(!tmp[i])
{
trie[x].win=i;
break;
}
}
}
int main()
{
int n,k,i,win,loss;
while(cin>>n>>k)
{
for(i=0;i<MAXN;i++)
{
memset(trie[i].son,0,sizeof(trie[i].son));
trie[i].flag=0;
}
cnt=0;
for(i=0;i<n;i++)
{
scanf(" %s",&s);
insert(s);
}
dfs(0);
win=trie[0].win;
loss=trie[0].loss;
if(win&&loss)
printf("First\n");
else if(win)
{
if(k&1)
printf("First\n");
else
printf("Second\n");
}
else
printf("Second\n");
}
}