HDU 2896 &HDU 3065

两道题调好久才调出来,最后发现3065是多组数据,(早知道就看discuss了)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2896
http://acm.hdu.edu.cn/showproblem.php?pid=3065

3065

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
    node *net[27];
    node *fail;
    int cnt,ld;
    node ()
    {
        fail=NULL;
        cnt=0;
        for (int i=0;i<27;i++)
        {
            net[i]=NULL;
        }
    }
}*e[100005],*root;
int ans[1005],tail=1,tou,n,m,cnt,flag[510],len,vis[1005];
char s[2000005],s1[1005][55];
void build_trie(char *S,int id)
{
    node *p=root;
    int temp;
    len=strlen (S);
    for(int i = 0; i < len; ++i)  
    {  
        temp = s1[id][i]-'A';  
        if(p->net[temp] == NULL)  
            p->net[temp] = new node();  
        p = p->net[temp];  
    }  
    p->cnt++;  
    p->ld=id;
}
void ac_build()
{
    int tou=0,tail=1;
    e[0]=root;
    root->fail=NULL;
    while (tou<tail)
    {
        node *p=e[tou++];
        node *temp=NULL;
       for(int i=0;i<26;i++)
        {
            if(p->net[i])
            {
                if(p==root)
                p->net[i]->fail=root;
                else
            {       
            node *pre=p->fail;
            while(pre)
            {
            if(pre->net[i])
            {
            p->net[i]->fail=pre->net[i];
            break;
            }
            pre=pre->fail;
            }
            if(!pre)
            p->net[i]->fail=root;
        } 
        e[tail++]=p->net[i];
        }
        }
  }
}
void query1()
{
    int id=0;
    memset(ans,0,sizeof(ans));
    node *p=root;
    int len=strlen(s);
    for (int i=0;i<len;i++)
    {
        if (s[i]>='A'&&s[i]<='Z') 
        {
            id=s[i]-'A';
            while(p!=root&&!p->net[id])
            p=p->fail;
            p=p->net[id];
            if(!p)
            p=root;
            node *tmp=p;
            while(tmp!=root&&tmp->cnt>0)
            {
                ans[tmp->ld]++;
                vis[tmp->ld]=1; 
                tmp=tmp->fail;
            }
        }else p=root;

    }
}
void readdata()
{

    while(scanf("%d",&n) == 1)
    {   
    memset(vis,0,sizeof(vis));
    root=new node();

    for (int i=1;i<=n;i++)
    {
        scanf("%s",s1[i]);
        build_trie(s1[i],i);
    }
    ac_build();
    cnt=0;
        int j,r=0;
        scanf("%s",s);
        query1();
        for (j=1;j<=n;j++)
        {   
        if (vis[j]==1)
        {
            printf("%s: %d",s1[j],ans[j]);
            printf("\n");
        }

        }
    }
}
int main()
{
    readdata();
}


----------
2896

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
    node *net[95];
    node *fail;
    int cnt;
    node ()
    {
        fail=NULL;
        cnt=0;
        for (int i=0;i<95;i++)
        {
            net[i]=NULL;
        }
    }
}*e[100005],*root;
int ans[1005],tail=1,tou,n,m,cnt,flag[510],len;
char s[10005],s1[505];
void build_trie(char *s,int id)
{
    node *p=root;
    int temp;
    len=strlen (s);
    for(int i = 0; i < len; ++i)  
    {  
        temp = s[i]-32;  
        if(p->net[temp] == NULL)  
            p->net[temp] = new node();  
        p = p->net[temp];  
    }  
    p->cnt=id;  
}
void ac_build()
{
    int tou=0,tail=1;
    e[0]=root;
    root->fail=NULL;
    while (tou<tail)
    {
        node *p=e[tou++];
        node *temp=NULL;
       for(int i=0;i<95;i++)
        {
            if(p->net[i])
            {
                if(p==root)
                p->net[i]->fail=root;
                else
            {       
            node *pre=p->fail;
            while(pre)
            {
            if(pre->net[i])
            {
            p->net[i]->fail=pre->net[i];
            break;
            }
            pre=pre->fail;
            }
            if(!pre)
            p->net[i]->fail=root;
        }
        e[tail++]=p->net[i];
        }
        }
  }
}
void query1()
{
    memset(ans,0,sizeof(ans));
    node *p=root;
    int len=strlen(s);
    for (int i=0;i<len;i++)
    {
        int id=s[i]-32;
        while(p!=root&&!p->net[id])
        p=p->fail;
        p=p->net[id];
        if(!p)
        p=root;
        node *tmp=p;
        while(tmp!=root)
        {
        if(tmp->cnt&&!ans[tmp->cnt])
        ans[tmp->cnt]=1;
        tmp=tmp->fail;
        }
    }
}
void readdata()
{

    while(~scanf("%d",&n))
    {   
    root=new node();
    for (int i=1;i<=n;i++)
    {
        scanf("%s",s1);
        build_trie(s1,i);
    }
    ac_build();
    scanf("%d\n",&m);
    cnt=0;
    for (int i=1;i<=m;i++)
    {
        int j,r=0;
        scanf("%s",s);
        query1();
        for (j=1;j<=n;j++)
            if (ans[j])
            {
                flag[r++]=j;
            }
            if (r)
            {
            printf("web %d:",i);
            for(j=0;j<r;j++)
            printf(" %d",flag[j]);
            printf("\n");
            cnt++;
            }
    }   
    printf("total: %d\n",cnt);
    }
}
int main()
{
    readdata();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值