HDU2896 AC Automata

Keywords: Java Eclipse ascii

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Problem Description
When the sun's glory is gradually obscured by the moon, the world loses its light, and the earth ushers in its darkest hour... At such moments, people are very excited - how happy it is that we can see the world wonder once in 500 years in our lifetime.~~
But there are always some websites on the internet, which began to spread viruses with the banner of introducing the solar eclipse by people's curiosity. Little t unfortunately became one of the victims. Xiao t was so angry that he decided to find out all the viral websites in the world. Of course, everyone knows it's impossible. Little T insisted on accomplishing the impossible task. He said, "There is an infinite shortage of children and grandchildren!" (Yu Gong has a successor.)
Everything is difficult at the beginning. Xiaot has collected many virus signatures and some source codes of weird websites. He wants to know which of these websites are viruses and what kind of viruses are they carrying. By the way, I also want to know how many viral websites he collects. At this time, he did not know where to start. So I would like to ask for your help. Little t is an acute person, so the sooner the problem is solved, the better.~~

Input
The first line, an integer N (1<=N<=500), represents the number of virus signatures.
Next, N lines, each representing a virus signature, the length of the signature string is between 20 and 200.
Each virus has a number, which is 1-N.
Virus signatures of different numbers will not be the same.
In the next line, there is an integer M (1<=M<=1000), which represents the number of websites.
Next, M lines, each representing a website source code, source string length between 7000 and 10000.
Each website has a number, which is 1-M.
All the characters in the above strings are ASCII code visible characters (excluding carriage return).

Output
The output format is as follows: output from small to large according to website number, virus-carrying website number and virus number, one poisonous website information per line.
web Site Number: Virus Number, Virus Number.
There is a space after the colon. Virus numbers are arranged from small to large. The two viruses are separated by a space. If a website contains viruses, the number of viruses will not exceed three.
The last line outputs statistics in the following format
total: Number of viral websites
There is a space after the colon.
Sample Input
3
aaa
bbb
ccc
2
aaabbbccc
bbaacc
Sample Output
web 1: 1 2 3
total: 1

The only difficulty is card memory (dynamic MLE to death). You can do it with C++.

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std ;
const int maxn = 201, maxm = 1e4+10 ;
int n, m, len ;
char tar[maxm] ;
bool used[501] ;
struct node {
    node* nxt[100] ;
    node *fa, *fail ;
    char ch ;
    int id ;
    node() {
        for ( int i = 0 ; i < 100 ; i ++ ) 
            nxt[i] = NULL ;
        id = 0 ;
        fa = fail = NULL ;
    }
} *h, *p, *q ;

void insert ( int id ) {
    p = h ;
    for ( int i = 1 ; i <= len ; i ++ ) {
        int index = tar[i]-' ' ;
        if ( p->nxt[index] ) p = p->nxt[index] ;
        else {
            ( p->nxt[index] = new node ) -> fa = p ;
            p = p->nxt[index] ;
            p->ch = index ;
        }
    }
    p->id = id ;
}

queue <node*> Q ;
void get_fail() {
    int s, t ;
    while ( !Q.empty() ) Q.pop() ;
    Q.push(h) ;
    while ( !Q.empty() ) {
        q = Q.front() ;
        Q.pop() ;
        for ( int i = 0 ; i < 100 ; i ++ ) {
            if ( q->nxt[i] ) {
                for ( p = q->fail ; p && !p->nxt[i] ; p = p->fail ) ;
                q->nxt[i]->fail = p? p->nxt[i] : h ;
                Q.push(q->nxt[i]) ;
            }
        }
    }
}

int s[501], cnt ;
void Match() {
    memset ( used, 0, sizeof(used) ) ;
    p = h ; 
    for ( int i = 1 ; i <= len ; i ++ ) {
        int index = tar[i]-' ' ;
        for ( ; p && !p->nxt[index] ; p = p->fail ) ;
        p = p? p->nxt[index]: h ;
        for ( q = p ; q ; q = q->fail) 
            if ( q->id && !used[q->id] ) ( s[++cnt] = q->id )[used] = true ;
    }
}

int main() {
    int i, j, k, tot = 0 ;
    h = new node ;
    scanf ( "%d", &m ) ;
    for ( i = 1 ; i <= m ; i ++ ) {
        scanf ( "%s", tar+1 ) ;
        len = strlen(tar+1) ;
        insert(i) ;
    }
    get_fail() ;

    scanf ( "%d", &n ) ;
    for ( i = 1 ; i <= n ; i ++ ) {
        scanf ( "%s", tar+1 ) ;
        len = strlen(tar+1) ;
        cnt = 0 ;
        Match() ;
        sort(s+1,s+cnt+1) ;
        if ( cnt ) {
            printf ( "web %d: ", i ) ;
            for ( j = 1 ; j < cnt ; j ++ ) 
                printf ( "%d ", s[j] ) ;
            printf ( "%d\n", s[cnt] ) ;
            ++ tot ;
        }
    }
    printf ( "total: %d\n", tot ) ;
    return 0 ;
}

Posted by virken on Thu, 11 Jul 2019 16:38:38 -0700