• 字符串游戏-博弈论-trie


    Description

      从前有个游戏。游戏分为 k 轮。

      给定一个由小写英文字母组成的字符串的集合 S,

      在每轮游戏开始时,双方会得到一个空的字符串,

      然后两人轮流在该串的末尾添加字符,并且需要保证新的字符串是 S 中某个串的前缀,直到有一方不能操作,则不能操作的一方输掉这一轮。

      新的一轮由上一轮输的人先手,最后一轮赢的人获得游戏胜利。

      假定双方都采取最优策略,求第一轮先手的一方能否获胜。

    Input

      输入包含多组数据。

      每组数据的第一行包含两个整数 n,k,分别表示字符串的数量和游戏的轮数。

      接下来 n 行,每行一个由小写英文字母组成的字符串。

    Output

      对于每组数据输出一行,若先手能获胜输出 HY wins!,否则输出 Teacher wins!

    Sample Input

      2 3
      a
      b
      3 1
      a
      b
      c

    Sample Output

      HY wins!
      HY wins!

    HINT

      1 ≤ n ≤ 1e5,1 ≤ k ≤ 1e9,保证所有字符串长度不超过 1e5,数据组数不超过 10。


    思路

    • 实现:f数组:两人都想赢时是否有必赢策略,g数组:两人都想输时是否有必输策略
    • 先手无必胜策略,则先手在k轮游戏中都是先手,必败;
    • 先手有必胜策略,无必败策略,则每轮游戏双方都会交换先后手,如果进行了奇数轮游戏,则先手必胜,否则先手必败;
    • 先手既有必胜策略也有必败策略,则先手可以在前k-1轮游戏中使用必败策略,在最后一轮使用必胜策略,因此先手必胜。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int n,k,cnt,f[1000005],g[1000005];
    char s[100005];
    struct fdfdfd{
    	int ch[27],flag;
    	void init(){memset(ch,0,sizeof(ch)); flag=0;}
    }e[1000005];
    void insert(char a[],int len)
    {
    	int root=1;
    	for(int i=0;i<len;++i)
    	{
    		int j=a[i]-'a'+1; e[root].flag=1;
    		if(!e[root].ch[j]) {e[root].ch[j]=++cnt; e[cnt].init();}
    		root=e[root].ch[j];
    	}
    }
    void dfs(int x)
    {
    	if(!e[x].flag) {g[x]=1; f[x]=0; return;}
    	f[x]=0; g[x]=0;
    	for(int i=1;i<=26;++i)
    	{
    		if(!e[x].ch[i]) continue;
    		dfs(e[x].ch[i]);
    		if(!f[e[x].ch[i]]) f[x]=1;
    		if(!g[e[x].ch[i]]) g[x]=1;
    	}
    }
    int main()
    {
    	while(scanf("%d%d",&n,&k)!=EOF)
    	{
    		cnt=1; e[1].init(); memset(f,0,sizeof(f)); memset(g,0,sizeof(g));
    		for(int i=1;i<=n;++i) scanf("%s",&s),insert(s,strlen(s));
    		dfs(1);
    		if((f[1]&&g[1])||(f[1]&&(k%2==1))) puts("HY wins!");
    		else puts("Teacher wins!");
    	}
    	return 0;
    }
    
  • 相关阅读:
    psp4
    一维循环数组最大子数组求解
    psp3
    psp2
    求二维数组最大连续子数组
    计算连续最大子数组问题
    psp1
    关于30道题目问题
    Java 文件操作
    java iterator
  • 原文地址:https://www.cnblogs.com/wuwendongxi/p/13773380.html
Copyright © 2020-2023  润新知