2009ACM多校联合暑期集训(10)——NIT专场

2009ACM多校联合暑期集训(10)——NIT专场

病毒侵袭

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 415    Accepted Submission(s): 48


Problem Description
当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻。。。。在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事儿啊~~
但 网路上总有那么些网站,开始借着民众的好奇心,打着介绍日食的旗号,大肆传播病毒。小t不幸成为受害者之一。小t如此生气,他决定要把世界上所有带病毒的 网站都找出来。当然,谁都知道这是不可能的。小t却执意要完成这不能的任务,他说:“子子孙孙无穷匮也!”(愚公后继有人了)。
万事开头难,小t 收集了好多病毒的特征码,又收集了一批诡异网站的源码,他想知道这些网站中哪些是有病毒的,又是带了怎样的病毒呢?顺便还想知道他到底收集了多少带病毒的 网站。这时候他却不知道何从下手了。所以想请大家帮帮忙。小t又是个急性子哦,所以解决问题越快越好哦~~
 

Input
第一行,一个整数N(1<=N<=500),表示病毒特征码的个数。
接下来N行,每行表示一个病毒特征码,特征码字符串长度在20—200之间。
每个病毒都有一个编号,依此为1—N。
不同编号的病毒特征码不会相同。
在这之后一行,有一个整数M(1<=M<=1000),表示网站数。
接下来M行,每行表示一个网站源码,源码字符串长度在7000—10000之间。
每个网站都有一个编号,依此为1—M。
以上字符串中字符都是ASCII码可见字符(不包括回车)。
 

Output
依次按如下格式输出按网站编号从小到大输出,带病毒的网站编号和包含病毒编号,每行一个含毒网站信息。
web 网站编号: 病毒编号 病毒编号 …
冒号后有一个空格,病毒编号按从小到大排列,两个病毒编号之间用一个空格隔开,如果一个网站包含病毒,病毒数不会超过3个。
最后一行输出统计信息,如下格式
total: 带病毒网站数
冒号后有一个空格。
 

Sample Input
3
aaa
bbb
ccc
2
aaabbbccc
bbaacc
 

Sample Output
web 1: 1 2 3
total: 1

裸的AC自动机
code:
#include < iostream >
using   namespace  std;

struct  tree
{
    tree 
* fail, * next[ 128 ];
    
int   cnt;
}
* root, * p;

tree arr[
1000001 ];
int   index,n, m;

tree 
* que[ 1000001 ];

char  let = 0 ;

void  newn()
{
    arr[index].cnt
= 0 ;
    
for ( int  i = 0 ;i < 128 ;i ++ ) arr[index].next[i] = 0 ;
    arr[index].fail
= NULL;
}

void  insert( char  ch[], int  w)
{
    p
= root;
    
int  i = 0 ,tmp;
    
while (ch[i])
    {
        tmp
= ch[i] - let;
        
if (p -> next[tmp] == 0 )
        {
            newn();
            p
-> next[tmp] =& arr[index ++ ];
        }
        p
= p -> next[tmp];
        i
++ ;
    }
    p
-> cnt  =  w;
}

void  get_fail()
{
    tree 
* q;
    p
= root; p -> fail = root;
    
int  open =- 1 ,close =- 1 ,i;
    
for (i = 0 ;i < 128 ;i ++ )
    {
        
if (p -> next[i] == 0 ) p -> next[i] = root;
        
else
        {
            p
-> next[i] -> fail = root;
            open
++ ;
            que[open]
= p -> next[i];
        }
    }
    
while (close < open)
    {
        close
++ ;
        q
= que[close];
        
for (i = 0 ;i < 128 ;i ++ )
        {
            
if (q -> next[i] == 0 ) q -> next[i] = q -> fail -> next[i];
            
else
            {
                q
-> next[i] -> fail = q -> fail -> next[i];
                open
++ ;
                que[open]
= q -> next[i];
            }    
        }
    }
}

int  a[ 5 ], len;

int  query( char  ch[])
{
    
int  num = 0 ;
    p
= root;
    tree 
* q;
    
int  tmp,i = 0 ;
    len 
=   - 1 ;
    a[
0 =  a[ 1 =  a[ 2 =   - 1 ;
    
while (ch[i])
    {
        tmp
= ch[i] - let;
        p
= p -> next[tmp];
        q
= p;
        
while (q -> cnt)
        {
            
if (q -> cnt  !=  a[ 0 &&  q -> cnt  !=  a[ 1 &&  q -> cnt  !=  a[ 2 ])
            {
                len 
++ ;
                a[len] 
=  q -> cnt;
            }
            
// q->cnt=0;
            q = q -> fail;
        }
        i
++ ;
    }
    
return  len;
}

char  s[ 10005 ];
int  main()
{
    
int  t;

    
while (scanf( " %d " , & n)  !=  EOF)
    {
        getchar();
        
int  i;
        index
= 0 ;
        newn();
        root
=& arr[index ++ ];
        
char  ch[ 201 ];
        
for (i = 1 ;i <= n;i ++ )
        {   
            gets(ch);
            insert(ch,i);
        }
        get_fail();
        
        scanf(
" %d " , & m);getchar();
        
int  cnt  =   0 ;
        
for (i  =   1 ;i  <=  m; i  ++ )
        {
            gets(s);
            
int  tmp  =  query(s);
            
if (tmp  >=   0 )
            {
                
int  j, k;
                cnt 
++ ;
                printf(
" web %d: " ,i);
                
for (j  =   0 ; j  <=  tmp; j  ++ )
                
for (k  =  j + 1 ;k <= tmp; k  ++ )
                
if (a[j]  >  a[k]) swap(a[j],a[k]);
                
for (j = 0 ;j <= tmp;j ++ )    printf( "  %d " ,a[j]); putchar( ' \n ' );
            }
        }
        printf(
" total: %d\n " ,cnt);
    }
}

你可能感兴趣的:(2009ACM多校联合暑期集训(10)——NIT专场)