这道题大家都暴力过了,因为题目数据小 ,但如果数据大了肿么办~~,这道题还可以 用后缀数组+栈扫描 (或二分)解. 不过效率很都不如后缀自动机。
姑且用它来练练后缀自动机吧
#include<stdio.h>
#include<string.h>
#include <cmath>
#include<algorithm>
#define fr(i,s,n) for(int i=s;i<n;i++)
#define fi freopen("in.txt","r",stdin)
#define fo freopen("output.txt","w",stdout)
#define cl(a) memset(a,0,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=130;
const int kinds=26;
char ch[maxn];
struct Sam{
Sam *son[kinds],*fa;
int l ,mlcs,nowlcs;
int fach,pos;
}a[maxn],*head,*last;
int top=-1;
Sam *b[maxn];
int dws[maxn],len;
void init(){
top = -1;
a[0].l = 0;
fr(i , 0 ,maxn) {
a[i].fa = NULL;
a[i].nowlcs = 0;
fr(k,0,kinds) a[i].son[k] = NULL;
cl(dws);
}
}
void add(int x,int pos){
Sam *p=&a[++top],*bj=last;
p->pos = pos,p->l= p->mlcs =last->l+1;last=p;
for(; bj && !bj->son[x] ; bj = bj->fa) bj->son[x] = p;
if (!bj) {p->fa = head;}
else if (bj->l+1 == bj->son[x]->l) p->fa = bj->son[x];
else{
Sam *r = &a[ ++ top],*q = bj->son[x]; r->pos = pos;
*r = *q ,r->l= r->mlcs = bj->l+1, p->fa = q->fa = r;
for( ; bj && bj->son[x] == q; bj = bj->fa) bj->son[x] = r;
}
}
char str[100];
struct Anscer{
char A[61];
}Ans[61];
bool cmp(Anscer x,Anscer y){
return strcmp(x.A,y.A)<= 0;
}
int main(){
int t,tot;
scanf("%d",&t);
while(t--){
init();
scanf("%d",&tot); --tot;
scanf("%s",ch);strcpy(str,ch);
head = last = &a[++top];
int n=strlen(ch);
fr(i,0,n) add( ch[i] - 'A',i);
int i;
for (i = 0; i <= top; ++i) ++dws[a[i].l];
for (i = 1; i <= n; ++i) dws[i] += dws[i - 1];
for (i = 0; i <= top; ++i) b[--dws[a[i].l]] = &a[i];
while(tot--){
scanf("%s",ch);
len = strlen(ch);
int mid = 0, y;
last = head;
for(int i=0;i<len;++i){
if (last ->son[y = ch[i] - 'A' ]){
++ mid;
last = last->son[y];
if (mid >last->nowlcs) last->nowlcs = mid;
}
else{
for (; last && !last->son[y]; last = last->fa);
if (!last) mid = 0,last = head;
else{
mid = last->l + 1;
last = last->son[y];
if (mid > last->nowlcs) last->nowlcs = mid;
}
}
}
for (int i=top ; i>0;--i){
if ( b[i]->nowlcs <b[i]->mlcs) b[i]->mlcs = b[i]->nowlcs;
if (b[i]->fa->nowlcs < b[i]->nowlcs) b[i]->fa->nowlcs = b[i]->nowlcs;
b[i]->nowlcs = 0;
}
}
int ans=0,anspos[61],totans=0;
fr(i , 0 ,top+1){
if (a[i].mlcs > ans) {
ans = a[i].mlcs;
totans =0;
anspos[totans++] = i;
}
else if (a[i].mlcs == ans){
anspos[totans++] = i;
}
}
if (ans<3){
printf("no significant commonalities\n");
}
else{
fr(i,0,totans){
int tmp = a[ anspos[i] ].pos;
int id=0;
for(int k = tmp - ans+1; k<=tmp ;k++){
Ans[i].A[id++] = str[k];
}
Ans[i].A[id] = '\0';
}
sort(Ans,Ans+totans,cmp);
printf("%s\n",Ans[0].A);
}
}
return 0;
}