这道题是一道典型的AC自动机,如果对AC自动机了解的话,很容易就能A出来,如果你是用指针写的话,会出现超内存的错误,因为我刚开始就是用指针写的,然后又各种从网上百度,百度到所有用指针写的,复制粘贴上去都出现超内存的错误,后来用了静态数组谢了之后就过了。这道题卡的点也有输入跟输出这一块。
用指针写的代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct node {
int count,index;
node *fail;
node *next[300];
node() {
index = 0;
fail = 0;
count=0;
memset(next,0,sizeof(next));
}
} *q[1000000];
int head=0,tail=0;
priority_queue<int, vector<int>, greater<int> > que;
node *root = new node(),*p1,*p2;
void insert(int num,char s[]) {
int i=0;
p1 = root;
while(s[i]) {
int val = (int)s[i] ;
if(p1->next[val] == 0) {
p2=new node();
p1->next[val] = p2;
p1 = p2;
}
else p1 = p1->next[val];
i++;
}
p1->index= num;
p1->count++;
}
void build_ac_automation() {
root->fail = 0;
q[head++] = root;
while(head != tail) {
p1 = q[tail++];
for(int i=0; i<300; i++) {
if(p1->next[i]) {
if(p1 == root) p1->next[i]->fail = root;
else {
p2=p1->fail;
while(p2) {
if(p2->next[i]) {
p1->next[i]->fail = p2->next[i];
break;
}
p2 = p2->fail;
}
if(p2 == 0) p1->next[i]->fail = root;
}
q[head++] = p1->next[i];
}
}
}
}
void query(char s[]) {
int i=0;
p1=root;
while(s[i]) {
int val = (int)s[i] ;
while(p1->next[val]==0 && p1!=root) p1 = p1->fail;
p1 = p1->next[val];
p1 = (p1==0) ? root : p1;
p2=p1;
while(p2!=root && p2->count!=-1) {
if(p2->count)
que.push(p2->index);
p2->count=-1;
p2 = p2->fail;
}
i++;
}
}
int main() {
int n,m,i,num=0;
char s[505],st[10010];
cin>>n;
for(i=1; i<=n; i++) {
cin>>s;
insert(i,s);
}
cin>>m;
build_ac_automation();
for(i=1; i<=m; i++) {
cin>>st;
while(!que.empty()) que.pop();
query(st);
if(!que.empty()) {
cout<<"web "<<i<<":";
while(!que.empty()) {
cout<<' '<<que.top();
que.pop();
}
cout<<endl;
num++;
}
}
cout<<"total: "<<num<<endl;
return 0;
}
用静态数组写的代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct node{
int next[500*210][128],fail[500*210],vis[500*210];
int sz,root;
int newnode() {
memset(next[sz],0,sizeof(next[sz]));
vis[sz++] = 0;
return sz-1;
}
void init() {
sz=0;
root = newnode();
}
void insert(char s[],int id) {
int i,pre=root;
for(i=0; s[i]; i++) {
if(next[pre][s[i]] == 0) {
int now=newnode();
next[pre][s[i]] = now;
pre = now;
}
else pre = next[pre][s[i]];
}
vis[pre] = id;
}
void build_ac_automation() {
queue<int> que;
fail[root] = root;
for(int i=0; i<128; i++) {
if(next[root][i] == 0) next[root][i] = root;
else {
fail[next[root][i]] = root;
que.push(next[root][i]);
}
}
while(!que.empty()) {
int temp=que.front();
que.pop();
for(int i=0; i<128; i++) {
if(next[temp][i]==0) {
next[temp][i] = next[fail[temp]][i];
}
else {
fail[next[temp][i]] = next[fail[temp]][i];
que.push(next[temp][i]);
}
}
}
}
int flag[520];
int query(char s[]) {
int i,ans=0;
memset(flag,0,sizeof(flag));
int temp=root;
for(i=0; s[i]; i++) {
temp=next[temp][s[i]];
int p = temp;
while(p!=root) {
if(vis[p]) {
flag[vis[p]] = 1;
ans++;
}
p = fail[p];
}
}
return ans;
}
};
node ac;
int main() {
int n,m,i,num=0;
char s[210],str[10010];
scanf("%d",&n);
ac.init();
for(i=1; i<=n; i++) {
scanf("%s",s);
ac.insert(s,i);
}
ac.build_ac_automation();
scanf("%d",&m);
for(i=0; i<m; i++) {
scanf("%s",str);
if(ac.query(str)) {
printf("web %d:",i+1);
num++;
for(int j=0; j<520; j++) {
if(ac.flag[j]) printf(" %d",j);
}
printf("\n");
}
}
printf("total: %d\n",num);
return 0;
}