Codeforces Round #260 (Div. 1) B. A Lot of Games Trie + 博弈

来源:互联网 发布:java中的多态 编辑:程序博客网 时间:2024/06/04 18:55

题意:两个人在Trie树上博弈k局,当前局输的人在下一局中执先手。在一局博弈中,当一个人不能走时,判定另一个人赢。最后一局的结果作为整个游戏的结果。

分析:先手赢的情况为:(1)先手可必胜,也 可败。那么前k-1局败,最后一局胜利即可。

(2)先手只能必胜。 当k为奇数时获胜。

   后手赢的情况为:(1)先手必败。

(2)先手只能必胜。 k为偶数。


(本题的状态为取完当前节点的状况)

判定先手是否可必胜:叶子节点为可必胜。如果一个节点的后继存在必胜,那么此节点为必败。如果一个节点的后继全为必败,那么此节点为必胜。


那么判定是否可败也是这样类似:叶子节点为不可败。如果一个节点的后继存在可败,那么此节点为不可败。如果一个节点的后继全为不可败,那么此节点为可败。

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int maxn = 1e5+10;const int ALP=26;struct Trie{    int next[maxn][ALP],dp[maxn],dp2[maxn];    int root,p;    int newnode(){        for(int i=0;i<ALP;i++)            next[p][i] = -1;        return p++;    }    void init(){        p = 0;        root = newnode();    }    void insert(char *buf){        int len = strlen(buf);        int now = root;        for(int i=0;i<len;i++){            int c = buf[i]-'a';            if(next[now][c]==-1)                next[now][c] = newnode();            now = next[now][c];        }    }    int dfs(int x){        int co=0 , win = 0;        for(int i=0;i<ALP;i++)if(next[x][i]!=-1){            int u = next[x][i];            win += dfs(u);            co++;        }        if(co==0) return dp[x] = 1;        else if(co>0 && win>0) return dp[x] = 0;        else return dp[x] = 1;    }    int dfs2(int x){        int co=0, fail = 0;        for(int i=0;i<ALP;i++)if(next[x][i]!=-1){            int u = next[x][i];            fail += dfs2(u);            co++;        }        if(co==0) return dp2[x] = 0;        else if(co>0 && fail==0) return dp2[x] = 1;        else return dp2[x] = 0;    }    void solve(int k){        int ok1=0 , ok2=0;        dfs(root);        for(int i=0;i<ALP;i++)if(next[root][i]!=-1){            int u = next[root][i];            if(dp[u]==1) ok1 = 1;        }        dfs2(root);        for(int i=0;i<ALP;i++)if(next[root][i]!=-1){            int u = next[root][i];            if(dp2[u]==1) ok2 = 1;        }        if(ok1==0){            puts("Second");        }else{            if(ok2==0){                if(k&1) puts("First");                else puts("Second");            }else{                puts("First");            }        }    }}tr;char s[maxn];int main(){    int n,k;    tr.init();    scanf("%d%d",&n,&k);    for(int i=1;i<=n;i++){        scanf("%s",s);        tr.insert(s);    }    tr.solve(k);    return 0;}


0 0
原创粉丝点击