#include<bits/stdc++.h>
using namespace std;
#define pos(x,y) s[x%y][x/y%len[x%y]]-'a' //求第x个加入的字符转换为二进制后在哪一位
typedef long long ll;
int len[101],cnt[26];
char s[101][13];
int t,n;
int main()
{
int f1,f2;//标记出现的所有字符
int ml,mg;//ml标记字符串最大长度,mg标记最小公倍数
scanf("%d",&t);
while(t--){
f1=f2=ml=0;
mg=1;
scanf("%d",&n);
memset(cnt,0,sizeof(cnt));
for(int i=0;i<n;i++){//按0~n-1存储,才能%n,故p2从-1开始
scanf("%s",s[i]);
len[i]=strlen(s[i]);
for(int j=0;j<len[i];j++) f1|=1<<s[i][j]-'a';//f1标记每组数据的所有字符串共出现哪些字母
if(len[i]>ml) ml=len[i];
mg=mg*len[i]/__gcd(mg,len[i]);
}
int p1=0;
int p2=-1;
int tot=(mg+ml)*n;
int res=tot;//res标记各个不同起点中最短的
while(p2<tot){
//2个while表示双指针p1和p2的移动方式
while(f2!=f1&&p2<tot){//因为p2++,故要再次判断p2<tot
p2++;
cnt[pos(p2,n)]++;//存各26个字母出现次数
f2|=1<<pos(p2,n);
}
while(f2==f1){//不用if,因为f2不断变化
res=min(res,p2-p1+1);
cnt[pos(p1,n)]--;
if(cnt[pos(p1,n)]==0) f2&=~(1<<pos(p1,n));//删去起始位的字母
p1++;
}
}
printf("%d\n",res);
}
return 0;
}
hdu7101滑动窗口(双指针)
最新推荐文章于 2021-09-11 17:21:57 发布