zoukankan      html  css  js  c++  java
  • The Dominator of Strings HDU

    题意:

      就是求是否有一个串 是其它所有串的母串

    解析:

      把所有的串都加入到trie数中  然后用最长的串去匹配就好了

    emm。。开始理解错题意了。。。看成了只要存在一个串是另一个的母串就好。。

    然后输出这样的串。。。用后缀数组写完后。。。才发现  理解错了 emm。。

    指针的会超时emm。。。然后才学了 用数组写

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<string>
    #include<iostream>
    #define maxn 1000010
    using namespace std;
    int n;
        int nxt[maxn][30],fail[maxn],edd[maxn],root,L;//nxt记录节点,在这里edd指针代表以当前节点为字符串尾的字符串个数
        int vis[maxn];
        int newnode()
        {
            for(int i=0;i<26;i++)
                nxt[L][i]=-1;//节点连接的边初始化为-1
            edd[L]=0;
            vis[L]=0;
            return L++;
        }
        void init()
        {
            L=0;
            root=newnode();
        }
    
        void insert(char *str)//trie树的建立
        {
            int l = strlen(str);
            int now=root;
            for(int i=0;i<l;i++)
            {
                int x = str[i] - 'a';
                if(nxt[now][x]==-1)nxt[now][x]=newnode();
                now=nxt[now][x];
            }
            edd[now]++;
        }
        void build()//建立ac自动机
        {
            queue<int> Q;
            for(int i=0;i<26;i++)
            {
                if(nxt[root][i]==-1)nxt[root][i]=root;
                else                                 //若有连边则将节点加入队列 ,并将fail指针指向root
                {
                    fail[nxt[root][i]]=root;
                    Q.push(nxt[root][i]);
                }
            }
            while(!Q.empty())
            {
                int now=Q.front();
                Q.pop();
                for(int i=0;i<26;i++)
                {
                    if(nxt[now][i]==-1)            //若无连边,则将该边指向当前节点fail指针指向的相应字符连接的节点
                        nxt[now][i]=nxt[fail[now]][i];
                    else                            //若有连边,则将儿子节点的fail指针指向当前节点fail指针指向相应字符接的节点
                    {
                        fail[nxt[now][i]]=nxt[fail[now]][i];
                        Q.push(nxt[now][i]); //加入队列继续遍历
                    }
                }
            }
        }
        int query(char str[])
        {
            int l = strlen(str);
            int now=root;
            int res=0;
            for(int i=0;i<l;i++)
            {
                int x = str[i] - 'a';
                now=nxt[now][x];
                int temp=now;
                while(temp!=root&&vis[temp]==0)//根据题目要求改变形式
                {
                    res+=edd[temp];
                    edd[temp]=0;
                    vis[temp]=1;
                    temp=fail[temp];
                }
            }
            return res; //在这里返回的是匹配到的模式串的数量
        }
    char str[maxn], ans[maxn];
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            init();
            int ma=0;
            for(int i=0;i<n;i++)
            {
                scanf("%s",str);
                int l=strlen(str);
                if(ma<l)
                {
                    ma=l;
                    strcpy(ans,str);
                }
                insert(str);
            }
            build();
            int sum=query(ans);
            if(sum==n) puts(ans);
            else puts("No");
        }
    }
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    [51nod1247]可能的路径(思维题)
    天梯赛L1020 帅到没朋友(map的使用)(模拟,数组非排序去重)
    洛谷 p1030 树的遍历
    天梯赛L1046 整除光棍(模拟)
    牛客,并查集,简单dp经商
    天梯赛L1043 阅览室 模拟题
    天梯赛L1049(模拟+vector的使用)
    天梯赛L1011,简单模拟
    codeforces 1201 c
    天梯赛L2003月饼(简单排序题)
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9507369.html
Copyright © 2011-2022 走看看