题意 就是给你N 个单词 和 一篇文章;然后问你 在这篇文章里面有多少个 出现的单词;如果一个单词是一个单词的字串,则只能算一个;
方法 首先用最简单的方法 把字符串解码,然后用模板跑一遍,找到所有单词,然后再用着写被标记的单词 插入字典树,把一路上的字符全部标记;
#include<iostream> #include<stdio.h> #include<cstring> #include<algorithm> using namespace std; char cha[2550][1123],str[5123456],sss[5123456]; bool vis[2550]; structdate { date *next[26],*fail; int tab; bool flag; }tree[3123456],*que[3123456],*root; int tail,head,ptr,N; date *creat_node( ) { for( int i = 0; i < 26; i++ ) tree[ptr].next[i] = NULL; tree[ptr].fail = NULL; tree[ptr].tab = 0; tree[ptr].flag = false; return &tree[ptr++]; } void inint( ) { tail = head = ptr = 0; root = creat_node( ); root->fail = root; } void insert( char *word,int i ) { date *temp = root; while( *word ) { int num = *word - 'A'; if( temp->next[num] == NULL ) temp->next[num] = creat_node( ); temp = temp->next[num]; word++; } temp->tab = i; } void build_AC( ) { que[tail++] = root; while( tail > head ) { date *temp = que[head++]; for( int i = 0; i < 26; i++ ) if( temp->next[i] != NULL ) { if( temp == root ) temp->next[i]->fail = root; else temp->next[i]->fail = temp->fail->next[i]; temp->next[i]->flag = true; que[tail++] = temp->next[i]; } else { if( temp == root ) temp->next[i] = root; else temp->next[i] = temp->fail->next[i]; } } } int query( char *word ) { date *patten,*temp = root; while( *word ) { int num = *word - 'A'; temp = temp->next[num]; patten = temp->fail; vis[temp->tab] = true; while( patten != root ) { if( patten->flag ) { patten->flag = false; vis[patten->tab] = false; } else break; patten = patten->fail; } word++; } for( int i = 1; i <= N; i++ ) { if( vis[i] ) { date *temp = root; int k = 0; int len = strlen(cha[i]) - 1; while( len-- ) { int num = cha[i][k++] - 'A'; temp = temp->next[num]; int t = temp->tab; if( vis[t] )vis[t] = false; } } } int ans = 0; for( int i = 1; i <= N; i++ ) if( vis[i] )ans++; return ans; } int deal( char *word,int t,int x) { bool fell = false; int len = strlen(word),num = 0,k = 0; for( int i = 0; i < len; i++ ) { if( fell ) { if( word[i] - '0' >= 0 && word[i] - '0' <= 9 ) num = num*10 + ( word[i] - '0' ); else { while( num-- )sss[k++] = word[i]; fell = false; } continue; } if( word[i] == '[' ) { fell = true; num = 0; continue; } if( (word[i] - 'A') >= 0 && (word[i] - 'A') <= 25 ) sss[k++] = word[i]; } sss[k] = '\0'; if( x ) { for( int i = 0; i < k; i++ ) cha[t][i] = sss[i]; cha[t][k] = '\0'; } else { for( int i = 0; i < k; i++ ) str[i] = sss[i]; str[k] = '\0'; } return 0; } int main( ) { int T,i,j; scanf("%d",&T); while( T-- ) { scanf("%d",&N); inint( ); for( i = 1; i <= N; i++ ) { scanf( "%s",&cha[i] ); deal(cha[i],i,1); insert( cha[i],i ); } build_AC( ); scanf("%s",&str); deal(str,0,0); memset( vis,false,sizeof(vis) ); printf("%d\n",query( sss )); } return 0; }