題目鏈接
http://acm.hdu.edu.cn/showproblem.php?pid=5880
Problem Description Steam is a digital distribution platform developed by Valve Corporation offering digital rights management (DRM), multiplayer gaming and social networking services. A family view can help you to prevent your children access to some content which are not suitable for them.
Recommend wange2014 | We have carefully selected several similar problems for you: 5901 5899 5898 5897 5896 題意:有n個由小寫字母構成的敏感詞,現在給了一個主串,要求將其中出現的敏感詞由“ * ” 代替 然後輸出這個主串; 思路:套用AC自動機模板,較快的處理方法是定義一個標記數組v[maxn] ,在主串中出現敏感詞的開始位置v[start]++,結束位置v[end+1]-- 最後在對主串輸出時,sum+=v[i], 如果sum>0 輸出“*” 否則輸出字符。 這題數據較大,很多人都一直爆內存,我也是~ 我在建立trie樹的時候用的鏈表,那麼每次插入新的節點時都開了一個節點的空間,每組數據算完後沒有清理這些空間,所以不管怎麼改一直爆內存,後來才發現,唉! 所以一定要注意清空內存哦! 代碼如下:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #define N 1000005 using namespace std; char str[1000005]; int v[1000005]; int head,tail; struct node { node *fail; node *next[26]; int count; node() { fail=NULL; count=0; for(short i=0;i<26;i++) next[i]=NULL; } }*q[N]; node *root; void insert(char *str) ///建立Trie { int temp,len; node *p=root; len=strlen(str); for(int i=0;i<len;i++) { temp=str[i]-'a'; if(p->next[temp]==NULL) p->next[temp]=new node(); p=p->next[temp]; } p->count=len; } void setfail() ///初始化fail指針,BFS { q[tail++]=root; while(head!=tail) { node *p=q[head++]; node *temp=NULL; for(short i=0;i<26;i++) if(p->next[i]!=NULL) { if(p==root) ///首字母的fail必指向根 p->next[i]->fail=root; else { temp=p->fail; ///失敗指針 while(temp!=NULL) ///2種情況結束:匹配為空or找到匹配 { if(temp->next[i]!=NULL) ///找到匹配 { p->next[i]->fail=temp->next[i]; break; } temp=temp->fail; } if(temp==NULL) ///為空則從頭匹配 p->next[i]->fail=root; } q[tail++]=p->next[i]; ///入隊; } } } void query() { node *p=root; int len=strlen(str); for(int i=0;i<len;i++) { int index; if(str[i]>='A'&&str[i]<='Z') index=str[i]-'A'; else if(str[i]>='a'&&str[i]<='z') index=str[i]-'a'; else { p=root; continue; } while(p->next[index]==NULL&&p!=root) ///跳轉失敗指針 p=p->fail; p=p->next[index]; if(p==NULL) p=root; node *temp=p; ///p不動,temp計算後綴串 while(temp!=root) { if(temp->count>0) { v[i-temp->count+1]++; v[i+1]--; break; } temp=temp->fail; } } return ; } int main() { int T, num; scanf("%d",&T); while(T--) { for(int i=0;i<tail;i++) free(q[i]); memset(v,0,sizeof(v)); head=tail=0; root = new node(); scanf("%d", &num); getchar(); for(int i=0;i<num;i++) { gets(str); insert(str); } setfail(); gets(str); int len=strlen(str),sum=0; query(); for(int i=0;i<len;i++) { sum+=v[i]; if(sum<=0) printf("%c",str[i]); else printf("*"); } puts(""); } return 0; }