A Lot of Games

原题:A Lot of Games

原题大意

给出N个字符串,有2名选手,s一开始是个空串,每回合轮流往里面填字母,使得s为N个字符串其中一个的字串,若不能再往里面填字母则输,输了的下回合先手,问最后一回合谁赢

算法分析

单局游戏可分成如下几种情况:
1.先手必胜(1,0) 2.先手必败(0,1) 3.先手可决定游戏胜败(1,1) 4.游戏胜败由后手决定 (0,0)
属于哪种情况,可种一棵字典树,然后dfs一遍,判断树上每个节点的状态。

情况1:两个玩家轮流胜利,第k局谁是胜者,由k的奇偶性决定。
情况2:很不幸,先手会一直输到底。
情况3:先手可前k-1局都输掉,在第k局击杀对手。
情况4:先手被后手按情况3的思路干掉。

程序代码

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 1e5+5;
const int SON = 26;
int node_num = 0, n, k; 
char s[maxn];
struct Node{
//    int cnt;
    Node *nxt[SON];
    void Init(){
  //      cnt = 0;
        memset(nxt, 0, sizeof(nxt));
    } 
}node[maxn];
Node * new_node(){
    node[node_num].Init();
    return &node[node_num++];
}
void Insert(Node * root, char *str){
    for(char *p = str; *p; p++)
    {
        int ch = *p - 'a';
        if(root->nxt[ch] == NULL)
            root->nxt[ch] = new_node();
        root = root->nxt[ch];
    //    root->cnt++;
    }
}
void solve(Node * root, int &x, int &y){
    bool fg = true;
    x = y = 0;
    int u, v;
    for(int i = 0; i < SON; i++)
    {
        if(root->nxt[i])
        {
            fg = false;
            solve(root->nxt[i],u, v);
            if(!u) x = 1;
            if(!v) y = 1;
        }
    }
    if(fg) x = 0, y = 1;
}
int main(){

        scanf("%d%d", &n, &k);
        Node * root = new_node();
        for(int i = 0; i < n; i++)
        {
            scanf("%s", s);
            Insert(root, s);
        }
        int x, y;
        solve(root, x, y);
        if(x && y) puts("First");
        else if((k&1) && x) puts("First");
        else puts("Second");

    return 0;
}