CF-456D- (trie + dp + game tree)

Meaning of the questions: http://codeforces.com/problemset/problem/456/D

Two can play the game. The game is spell the word, gives a thesaurus containing n-word. The current word is initially empty, everyone turns to add it at the end of a letter, any requirements of the current word is a word prefix lexicon, when a person can not lose him the letters. This game is repeated k Bureau, a bureau of people lose the upper hand next game, the last game will be played. Two people are not stupid, seeking the upper hand if you can guarantee the first inning finally win, you can output First, it can not output Second.

Ideas:

Trie supposed to think, I started to think of ac automata (really enough, how can there be so hard)

Dp about the game, then first determine whether the upper hand in a game of win or lose control of their state

Finally, for k discuss on the line

  1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
  2 #include <cstdio>//sprintf islower isupper
  3 #include <cstdlib>//malloc  exit strcat itoa system("cls")
  4 #include <iostream>//pair
  5 #include <fstream>//freopen("C:\\Users\\13606\\Desktop\\Input.txt","r",stdin);
  6 #include <bitset>
  7 //#include <map>
  8 //#include<unordered_map>
  9 #include <vector>
 10 #include <stack>
 11 #include <set>
 12 #include <string.h>//strstr substr strcat
 13 #include <string>
 14 #include <time.h>// srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
 15 #include <cmath>
 16 #include <deque>
 17 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
 18 #include <vector>//emplace_back
 19 //#include <math.h>
 20 #include <cassert>
 21 #include <iomanip>
 22 //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
 23 #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
 24 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
 25 //******************
 26 clock_t __START,__END;
 27 double __TOTALTIME;
 28 void _MS(){__START=clock();}
 29 void _ME(){__END=clock();__TOTALTIME=(double)(__END-__START)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;}
 30 //***********************
 31 #define rint register int
 32 #define fo(a,b,c) for(rint a=b;a<=c;++a)
 33 #define fr(a,b,c) for(rint a=b;a>=c;--a)
 34 #define mem(a,b) memset(a,b,sizeof(a))
 35 #define pr printf
 36 #define sc scanf
 37 #define ls rt<<1
 38 #define rs rt<<1|1
 39 typedef pair<int,int> PII;
 40 typedef vector<int> VI;
 41 typedef unsigned long long ull;
 42 typedef long long ll;
 43 typedef double db;
 44 const db E=2.718281828;
 45 const db PI=acos(-1.0);
 46 const ll INF=(1LL<<60);
 47 const int inf=(1<<30);
 48 const db ESP=1e-9;
 49 const int mod=(int)1e9+7;
 50 const int N=(int)1e5+10;
 51 
 52 int trie[N][26],tot;
 53 
 54 void insert(char s[])
 55 {
 56     int len=strlen(s);
 57     int root=0;
 58     for(int i=0;i<len;i++)
 59     {
 60         int id=s[i]-'a';
 61         if(!trie[root][id]) trie[root][id]=++tot;
 62         root=trie[root][id];
 63     }
 64 }
 65 
 66 char s[N];
 67 int dp[N][2];
 68 void dfs(int root,int c)
 69 {
 70     bool ok=0,no=0;
 71     bool ok2=1,no2=1;
 72     bool have=0;
 73     for(int i=0;i<=25;++i)
 74     {
 75         int to=trie[root][i];
 76         if(to)
 77         {
 78             have=1;
 79             dfs(to,c+1);
 80             if(dp[to][1])ok=1;
 81             if(dp[to][0])no=1;
 82             if(!dp[to][1])ok2=0;
 83             if(!dp[to][0])no2=0;
 84         }
 85     }
 86     if(!have)
 87     {
 88         if(c&1)dp[root][1]=1;
 89         else dp[root][0]=1;
 90         return ;
 91     }
 92     if(c&1)
 93     {
 94         if(ok2&&no2)
 95         {
 96             dp[root][0]=0;
 97             dp[root][1]=0;
 98         }
 99         else if(no2)
100         {
101             dp[root][0]=1;
102             dp[root][1]=0;
103         }
104         else if(ok2)
105         {
106             dp[root][0]=0;
107             dp[root][1]=1;
108         }
109     }
110     else
111     {
112         if(ok&&no)
113         {
114             dp[root][0]=1;
115             dp[root][1]=1;
116         }
117         else if(no)
118         {
119             dp[root][0]=1;
120             dp[root][1]=0;
121         }
122         else if(ok)
123         {
124             dp[root][0]=0;
125             dp[root][1]=1;
126         }
127     }
128 }
129 
130 int main()
131 {
132     int n,k;
133     sc("%d%d",&n,&k);
134     for(int i=1;i<=n;++i)
135     {
136         sc("%s",s);
137         insert(s);
138     }
139     dfs(0,0);
140     bool ok=0,no=0;
141     for(int i=0;i<=25;++i)
142     {
143         int to=trie[0][i];
144         if(to)
145         {
146             if(dp[to][1])ok=1;
147             if(dp[to][0])no=1;
148         }
149     }
150     bool ans=0;
151     if(ok&&no)
152     {
153         ans=1;
154     }
155     else if(ok)
156     {
157         if(k&1)ans=1;
158     }
159     if(ans)
160         pr("First\n");
161     else
162         pr("Second\n");
163     return 0;
164 }
165 
166 /**************************************************************************************/

 

Guess you like

Origin www.cnblogs.com/--HPY-7m/p/12589008.html