题目链接:
http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1003&cid=778
题解:
STM,队友讲题意的时候漏掉了范围。。。。。。
强行AC自动机。
代码:
#include<cstdio>
#include<cstring>
#define M 100000+10
using namespace std;
struct AC{
int root,en,my_que[M];
struct E{
int flag,fail;
int next[26];
}e[M];
void flash(int id){
e[id].flag=0;
memset(e[id].next,-1,sizeof(e[id].next));
}
void init(){
root=0;en=1;
flash(root);
e[root].fail=-1;
}
void insert(char *p){
int tr=root;
for(int i=0;p[i];i++){
int dex=p[i]-'a';
if(e[tr].next[dex]==-1){
int t2=en++;flash(t2);
e[tr].next[dex]=t2;
}
tr=e[tr].next[dex];
}
e[tr].flag++;
}
void build(){
int hp=0,tp=-1;
my_que[++tp]=root;
while(tp>=hp){
int now=my_que[hp++];
for(int i=0;i<26;i++){
if(e[now].next[i]!=-1){
int nxt=e[now].next[i];
int dex=i;
if(now==root){
e[nxt].fail=root;
}
else{
int tmp=e[now].fail;
while(tmp!=-1&&e[tmp].next[dex]==-1) tmp=e[tmp].fail;
if(tmp==-1) tmp=root;
else tmp=e[tmp].next[dex];
e[nxt].fail=tmp;
}
my_que[++tp]=nxt;
}
}
}
}
int query(char *p){
int ans=0;
int tr=root;
for(int i=0;p[i];i++){
int dex=p[i]-'a';
while(e[tr].next[dex]==-1&&tr!=root)tr=e[tr].fail;
tr=e[tr].next[dex];
if(tr==-1)tr=root;
int tmp=tr;
while(tmp!=root&&e[tmp].flag!=-1){
ans+=e[tmp].flag;
e[tmp].flag=-1;
tmp=e[tmp].fail;
}
}
return ans;
}
}ac;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
ac.init();
char pre[M],now[M];
int n;
scanf("%d",&n);
scanf("%s",pre);
int MAX=strlen(pre);
for(int i=1;i<n;i++)
{
scanf("%s",now);
int len=strlen(now);
if(len>MAX)
{
ac.insert(pre);
MAX=len;
strcpy(pre,now);
}
else
ac.insert(now);
}
ac.build();
int cnt=ac.query(pre);
if(cnt!=n-1)
printf("No\n");
else
printf("%s\n",pre);
}
}
本文通过一道编程竞赛题目,详细介绍了AC自动机的构建过程及其应用。文章分享了一个使用C++实现的AC自动机代码实例,包括初始化、插入字符串、构建失败指针以及查询等核心操作。

被折叠的 条评论
为什么被折叠?



