zoukankan      html  css  js  c++  java
  • [AC自己主动机] zoj Searching the String

    意甲冠军:

    到原始字符串。给n字符串,每个字符串都有一个属性,属性0代表重叠,1代表不能重叠

    请各多少次出现的字符串

    思维:

    为了便于建立两台机器自己主动(0一个。1一个)

    然后,它可以重叠非常好做,谁做

    不可重叠的话须要记录两个东西

    len[i]代表每一个串的长度,used[i]代表每一个串在之前出现的位置,初始化-1

    然后遍历到的时候对于当前位置 j。 必须j>=used[i]+len[i] 才干算出现。而且更新

    须要注意的是:

    会出现相同属性而且相同的串。

    我处理的方式就是排序。按id排序大的在前

    然后算一遍大的,用大的赋值给id 小的且串同样的。

    代码:

    #include"cstdlib"
    #include"cstdio"
    #include"cstring"
    #include"cmath"
    #include"queue"
    #include"algorithm"
    #include"iostream"
    using namespace std;
    char fuck[123456];
    int ans[123456],used[123456],len[123456];
    struct word
    {
        int x,id;
        char y[7];
    } dc[123456];
    struct trie
    {
        int mark;
        trie *next[27];
        trie *fail;
        trie()
        {
            mark=0;
            memset(next,0,sizeof(next));
            fail=NULL;
        }
    };
    trie *root0,*root1;
    void init(int key,char *v,int id)
    {
        trie *p;
        if(key) p=root1;
        else p=root0;
        for(int i=0; v[i]; i++)
        {
            int tep=v[i]-'a';
            if(p->next[tep]==NULL) p->next[tep]=new trie();
            p=p->next[tep];
        }
        p->mark=id;
    }
    void del(trie *p)
    {
        for(int j=0; j<26; j++) if(p->next[j]!=NULL) del(p->next[j]);
        free(p);
    }
    void getac()
    {
        queue<trie*>q;
        q.push(root0);
        while(!q.empty())
        {
            trie *p,*tep;
            p=q.front();
            q.pop();
            for(int i=0; i<26; i++)
            {
                if(p->next[i]!=NULL)
                {
                    if(p==root0) p->next[i]->fail=root0;
                    else
                    {
                        tep=p->fail;
                        while(tep!=NULL)
                        {
                            if(tep->next[i]!=NULL)
                            {
                                p->next[i]->fail=tep->next[i];
                                break;
                            }
                            tep=tep->fail;
                        }
                        if(tep==NULL) p->next[i]->fail=root0;
                    }
                    q.push(p->next[i]);
                }
            }
        }
        q.push(root1);
        while(!q.empty())
        {
            trie *p,*tep;
            p=q.front();
            q.pop();
            for(int i=0; i<26; i++)
            {
                if(p->next[i]!=NULL)
                {
                    if(p==root1) p->next[i]->fail=root1;
                    else
                    {
                        tep=p->fail;
                        while(tep!=NULL)
                        {
                            if(tep->next[i]!=NULL)
                            {
                                p->next[i]->fail=tep->next[i];
                                break;
                            }
                            tep=tep->fail;
                        }
                        if(tep==NULL) p->next[i]->fail=root1;
                    }
                    q.push(p->next[i]);
                }
            }
        }
    }
    void finde(char *v)
    {
        trie *p0=root0,*p1=root1;
        for(int i=0; v[i]; i++)
        {
            int tep=v[i]-'a';
            while(p0->next[tep]==NULL && p0!=root0)
                p0=p0->fail;
            p0=p0->next[tep];
            if(p0==NULL) p0=root0;
            trie *q0=p0;
            while(q0!=root0)
            {
                if(q0->mark!=0) ans[q0->mark]++;
                q0=q0->fail;
            }
            while(p1->next[tep]==NULL && p1!=root1)
                p1=p1->fail;
            p1=p1->next[tep];
            if(p1==NULL) p1=root1;
            trie *q1=p1;
            while(q1!=root1)
            {
                if(q1->mark!=0)
                {
                    if(i>=used[q1->mark]+len[q1->mark])  //不可重叠的推断
                    {
                        ans[q1->mark]++;
                        used[q1->mark]=i;
                    }
                }
                q1=q1->fail;
            }
        }
    }
    int cmp(word a,word b)  //排序的cmp
    {
        if(a.x==b.x)
        {
            if(strcmp(a.y,b.y)==0)
            {
                if(a.id>b.id) return 1;
                else return 0;
            }
            else
            {
                if(strcmp(a.y,b.y)>0) return 1;
                else return 0;
            }
        }
        else
        {
            if(a.x>b.x) return 1;
            else return 0;
        }
    }
    int main()
    {
        int cas=1;
        while(scanf("%s",fuck)!=-1)
        {
            int n;
            scanf("%d",&n);
            root0=new trie();
            root1=new trie();
            for(int i=1; i<=n; i++)
            {
                int x;
                char y[12];
                scanf("%d%s",&x,y);
                len[i]=strlen(y);
                init(x,y,i);
                dc[i].x=x;
                strcpy(dc[i].y,y);
                dc[i].id=i;
            }
            memset(ans,0,sizeof(ans));
            memset(used,-1,sizeof(used));
            getac();
            finde(fuck);
            sort(dc+1,dc+1+n,cmp);
            int i;
            for(i=1; dc[i+1].x==1; i++)  //赋值给那些反复的
            {
                if(strcmp(dc[i].y,dc[i+1].y)==0)
                    ans[dc[i+1].id]=ans[dc[i].id];
            }
            for(i=i+1; i<n; i++)
            {
                if(strcmp(dc[i].y,dc[i+1].y)==0)
                    ans[dc[i+1].id]=ans[dc[i].id];
            }
            printf("Case %d
    ",cas++);
            for(int i=1; i<=n; i++) printf("%d
    ",ans[i]);
            del(root0);
            del(root1);
            puts("");
        }
        return 0;
    }
    


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    权重
    盒模型
    认识html标签
    CSS盒子模型
    行内元素和块级元素的区别
    搭建线路mvc实现接口获取数据库数据
    实现车辆信息编辑功能
    最近系统更新进度截图
    最近没写什么---更新下,在家没键盘就偷懒了
    基于web公交查询系统----管理员公交站点管理页面实现
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4620259.html
Copyright © 2011-2022 走看看