http://acm.hust.edu.cn/vjudge/contest/view.action?cid=78124#problem/H
//想看题目的@willinglive
首先我们根据给出的字符串建立字典树
然后在字典树上dfs求出先手可否必赢和先手可否必输,记flag1和flag2
if(flag1)
{
if(flag2)
First
else
{
if(k%2==1)
First
else
Second
}
}
else
Second
然后就结束了
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int p;
int t[270001][27];
int sx1[2000001],sx2[2000001];
int ss;
inline void dfs1(int d,int tt)
{
int k;
if(tt%2==1)
sx1[d]=1;
else
sx1[d]=0;
for(k=0;k<=25;k++)
{
if(t[d][k]!=0)
{
dfs1(t[d][k],tt+1);
if(tt%2==1)
{
if(sx1[t[d][k]]==0)
sx1[d]=0;
}
else
{
if(sx1[t[d][k]]==1)
sx1[d]=1;
}
}
}
}
inline void dfs2(int d,int tt)
{
int k;
if(tt%2==1)
sx2[d]=0;
else
sx2[d]=1;
int s=0,s1=0;
for(k=0;k<=25;k++)
{
if(t[d][k]!=0)
{
dfs2(t[d][k],tt+1);
s++;
if(tt%2==1)
{
/*if(sx2[t[d][k]]==0)
sx2[d]=0;*/
if(sx2[t[d][k]]==1)
s1++;
}
else
{
/*if(sx2[t[d][k]]==1)
// s1++;
sx2[d]=1;*/
if(sx2[t[d][k]]==0)
s1++;
}
}
}
if(tt%2==1&&s!=0)
{
if(s1==s)
sx2[d]=1;
}
else if(s!=0)
{
if(s1==s)
sx2[d]=0;
}
}
int main()
{
int n,k;
scanf("%d%d",&n,&k);
int i,lx,j;
string s;
p++;
for(i=1;i<=n;i++)
{
cin>>s;
lx=s.size();
int temp=1;
for(j=1;j<=lx;j++)
{
int k=s[j-1]-'a';
if(t[temp][k]==0)
{
p++;
t[temp][k]=p;
temp=p;
}
else
temp=t[temp][k];
}
}
memset(sx1,-1,sizeof(sx1));
dfs1(1,0);
memset(sx2,-1,sizeof(sx2));
dfs2(1,0);
if(sx1[1]==1)
{
if(sx2[1]==1)
printf("First\n");
else
{
if(k%2==1)
printf("First\n");
else
printf("Second\n");
}
}
else
printf("Second\n");
return 0;
}