Codeforces Round #260 (Div. 2) D

来源:互联网 发布:java 1000以内的完数 编辑:程序博客网 时间:2024/05/22 05:16

D. A Lot of Games


        题意:博弈问题。两个人玩游戏。有n个字符串,两个人轮流往一个空串word里添加字母,每次添加后word必须是这n个字符串中某个(些)串的前缀。无法添加字母的一方输。然后他们要连续玩k次这个游戏,每次输的一方下一次游戏先行动。最后的那次游戏胜利才是最终的胜利。问开始先行动能赢还是后行动能赢。

        思路:字典树存串。然后遍历树来找先行动是否有必胜和必败策略。判断必胜如果有一条路能赢就是赢,否则输。判断必败同理。然后到底谁赢要将是否有必胜/必败策略和游戏次数结合起来判断。

        第一次写字典树,看着概念自己YY写的居然A了。。这个故事告诉我们,有些游戏里有必胜策略不一定有必败策略,有必败策略不一定有必胜策略,但是两者至少有其一。


#include <iostream>    #include <stdio.h>    #include <cmath>    #include <algorithm>    #include <iomanip>    #include <cstdlib>    #include <string>    #include <memory.h>    #include <vector>    #include <queue>    #include <stack>    #include <map>  #include <set>  #include <ctype.h>    #define INF 1000000  #define ll long long#define min3(a,b,c) min(a,min(b,c))  using namespace std;  struct node{char c;node* next[26];};void _insert(node* r,char* str,int len){node* cur=r;for(int i=0;i<len;i++){if(cur->next[str[i]-97]==0){cur->next[str[i]-97]=new node();cur->next[str[i]-97]->c=str[i];}cur=cur->next[str[i]-97];}}bool win(node* r){bool isnull=true;for(int i=0;i<26;i++){if(r->next[i]!=0)isnull=false;}//无路可走就输了 if(isnull)return false;for(int i=0;i<26;i++){if(r->next[i]==0)continue;if(!win(r->next[i]))return true;//能让别人无路可走就赢了 }//无法让别人无路可走就输了 return false;}bool lose(node* r){bool isnull=true;for(int i=0;i<26;i++){if(r->next[i]!=0)isnull=false;}if(isnull)return true;for(int i=0;i<26;i++){if(r->next[i]==0)continue;if(!lose(r->next[i]))return true;}return false;}int main(){int n,k;while(cin>>n>>k){node* root=new node();char str[100010];for(int i=1;i<=n;i++){cin>>str;_insert(root,str,strlen(str));}if(k&1){if(win(root)){cout<<"First"<<endl;}else{cout<<"Second"<<endl;}}else{if(win(root)&&lose(root)){cout<<"First"<<endl;}else{cout<<"Second"<<endl;}}}return 0;}



0 0