2017 ACM/ICPC Asia Regional Qingdao Online C The Dominator of Strings

来源:互联网 发布:如何查看域名对应的ip 编辑:程序博客网 时间:2024/06/14 09:07

题意:给N个串,如果有一个串,其他所有的串都是它的子串,它是“字符统治者”,输入它,没有则输出No.


比赛用以前指针版AC自动机各种MLE,加释放内存TLE,还是得改模板,数组版AC(但还是没字典树的快)

#include<cstdio>#include<cstring>#include<queue>#define maxn 100005using namespace std;int n;struct  Trie{    int nxt[maxn][30],FAIL[maxn],edd[maxn],root,L;//nxt记录节点,在这里edd指针代表以当前节点为字符串尾的字符串个数    int newnode()    {        for(int i=0;i<26;i++)            nxt[L][i]=-1;//节点连接的边初始化为-1        edd[L]=0;        return L++;    }    void init()    {        L=0;        root=newnode();    }    void insert(char buf[],int l)//trie树的建立    {        int now=root;        for(int i=0;i<l;i++)        {            if(nxt[now][buf[i]-'a']==-1)nxt[now][buf[i]-'a']=newnode();            now=nxt[now][buf[i]-'a'];        }        edd[now]++;    }    void build()//建立ac自动机    {        queue<int>que;        for(int i=0;i<26;i++)        {            if(nxt[root][i]==-1)nxt[root][i]=root;            else                                 //若有连边则将节点加入队列 ,并将FAIL指针指向root            {                FAIL[nxt[root][i]]=root;                que.push(nxt[root][i]);            }        }        while(!que.empty())        {            int now=que.front();            que.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];                    que.push(nxt[now][i]); //加入队列继续遍历                }            }        }    }    int query(char buf[],int l)    {        int now=root;        int res=0;        for(int i=0;i<l;i++)        {            now=nxt[now][buf[i]-'a'];            int temp=now;            while(temp!=root&& edd[temp]!=-1)//根据题目要求改变形式            {                res+=edd[temp];                edd[temp]=-1;                temp=FAIL[temp];            }        }        return res; //在这里返回的是匹配到的模式串的数量    }};char buf[maxn],ans[maxn];Trie ac;int main(){    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        ac.init();        int maxlen=-1;        for(int i=0;i<n;i++)        {            scanf("%s",buf);            int len=strlen(buf);            if(maxlen<len)            {                maxlen=len;                strcpy(ans,buf);            }            ac.insert(buf,len);        }        ac.build();        int sum=ac.query(ans,maxlen);        if(sum==n) puts(ans);        else puts("No");    }}

Sunday,比赛时候WA了,可能是模板打错了。。

#include <iostream>  #include <cstring>#include<string>#include <cstdio>using namespace std;  const int maxn=100005;string str[maxn];int sunday(char *text, char *patt){    size_t temp[256];    size_t *shift = temp;    size_t i, patt_size = strlen(patt), text_size = strlen(text);   // cout << "size : " << patt_size << endl;    for(i = 0; i < 256; i++)    {        *(shift+i) = patt_size + 1;    }    for(i = 0; i < patt_size; i++)    {        *(shift + (unsigned char)(*(patt+i))) = patt_size-i;    //  shift['s']=6步,shitf['e']=5以此类推    }    size_t limit = text_size - patt_size + 1;    for(i = 0; i < limit; i += shift[text[i + patt_size]])    {        if(text[i] == *patt)        {            char *match_text = text + i + 1;            size_t match_size = 1;            do              {                if(match_size == patt_size)                {                    return 1;                }            }            while((*match_text++) == patt[match_size++]);        }    }        return 0;}int main(void){    ios::sync_with_stdio(false);    int T;    cin>>T;    while(T--)    {        int N;        cin>>N;        if(N==1)        {            cin>>str[0];            cout<<str[0]<<endl;        }        else{            int maxlen=0,maxpo=0;            bool bo=true;            for(int i=0;i<N;i++)            {                cin>>str[i];                int temp=str[i].length();                if(temp>maxlen)                {                    maxlen=temp;                maxpo=i;                }            }            for(int i=0;i<N;i++)            {                if(i!=maxpo)                {                    int ans=sunday((char *)str[maxpo].c_str(),(char *)str[i].c_str());                    if(ans==0)                    {                        bo=false;                        break;                        }                 }            }            if(bo==true)            cout<<str[maxpo]<<endl;             else              cout<<"No"<<endl;        }    } return 0;} 


队友的字典树:

#include <cstdio>#include <iostream>#include <algorithm>#include <queue>#include <cmath>#include <cstring>#include <stack>#include <set>#include <map>#include <vector>using namespace std;#define INF 0x2fffffff#define LL long long#define MAX(a,b) ((a)>(b))?(a):(b)#define MIN(a,b) ((a)<(b))?(a):(b)#define id(a) ((a)-'a')const int maxnode = 10000*50+10;int ch[maxnode][26];int val[maxnode];int sz = 0;int insert(char *s){    int len =strlen(s);    int u = 0;    for(int i = 0;i < len;i++){        int c = id(s[i]);        if(!ch[u][c]){            memset(ch[sz],0,sizeof(ch[sz]));            val[sz] = 0;            ch[u][c] = sz++;        }        u = ch[u][c];               }    val[u] ++;}int query(char *s){    int ans = 0;    for(int i = 0;s[i];i++){        int c = id(s[i]);        int u = 0;        int j = 0;        while(ch[u][c]){            if(val[ch[u][c]]){                ans += val[ch[u][c]];                val[ch[u][c]] = 0;            }            u = ch[u][c];            j ++;            c = id(s[i+j]);        }    }    return ans;}char s[100001]; int main(){    int t;    //freopen("1.txt","r",stdin);    //freopen("2.txt","w",stdout);    scanf("%d",&t);    while(t--){        int n;        scanf("%d",&n);        char a[100001];        memset(ch[0],0,sizeof(ch[0]));        val[0]= 0;        sz = 1;        int maxl=-1;        for(int i = 0;i < n;i++){            scanf("%s",a);            int len=strlen(a);            if(len>maxl)            {                memcpy(s,a,len+1);                maxl=len;            }            insert(a);        }        if(query(s)==n)printf("%s\n",s);        else printf("No\n");            }    return 0;}

最后留个Sunday模板:

int SundaySearch(string text, string pattern){    int i = 0, j = 0, k;    int m = pattern.size();    if(pattern.size() <= 0 || text.size() <= 0)        return -1;    for(; i<text.size();) {        if(text[i] != pattern[j]) {            for(k=pattern.size() - 1; k>=0; k--) {                if(pattern[k] == text[m])                     break;            }            i = m-k;            j = 0;            m = i+pattern.size();        }        else {            if(j == pattern.size()-1)                return i-j;            i++;            j++;        }    }    return -1;}

阅读全文
0 0
原创粉丝点击