题目大意:给定 n 个A串和 n 个B串,长度均为 m ,求一个最短的区间 [l,r] ,使得不存在一个A串 a 和一个B串 b ,使得 a[l,r]=b[l,r]
n,m≤500
枚举区间左端点,然后Trie树直接模拟就行了
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 550
using namespace std;
int n,m,ans=0x3f3f3f3f;
struct Trie
{
static Trie mempool[M*M<<1],*C;
Trie *son[4];
bool flag;
void* operator new(size_t)
{
memset(C,0,sizeof(Trie));
return C++;
}
static void Initialize()
{
C=mempool;
}
Trie* Trans(char c)
{
int i;
switch(c)
{
case 'A':i=0;break;
case 'C':i=1;break;
case 'G':i=2;break;
case 'T':i=3;break;
}
if(!son[i])
son[i]=new Trie;
return son[i];
}
}*root,*spt[M],*pln[M];
Trie Trie::mempool[M*M<<1];
Trie* Trie::C;
char spt_gen[M][M];
char pln_gen[M][M];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
scanf("%s",spt_gen[i]+1);
for(int i=1;i<=n;i++)
scanf("%s",pln_gen[i]+1);
for(int st=1;st<=m;st++)
{
Trie::Initialize();
root=new Trie;
for(int i=1;i<=n;i++)
spt[i]=root;
for(int i=1;i<=n;i++)
pln[i]=root;
for(int j=st;j<=m;j++)
{
bool flag=false;
for(int i=1;i<=n;i++)
{
spt[i]=spt[i]->Trans(spt_gen[i][j]);
spt[i]->flag=true;
}
for(int i=1;i<=n;i++)
{
pln[i]=pln[i]->Trans(pln_gen[i][j]);
if(pln[i]->flag)
flag=true;
}
if(!flag)
{
ans=min(ans,j-st+1);
break;
}
}
}
cout<<ans<<endl;
return 0;
}