5-14 数据结构啊poi H.许多的游戏

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值