- 思路
有人说是这个字符串的循环节是
l
c
m
∗
2
∗
n
lcm*2*n
lcm∗2∗n,没错就是 糊神 说的。
剩下的就是板子,滑动窗口/双指针 - 代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e3+10,mod=1e9+7;
template<typename T>
void Debug(T x,string s){
cout<<s<<": "<<x<<endl;
}
#define PII pair<int,int>
#define x first
#define y second
#define PB push_back
string str[N];
ll gcd(ll a,ll b)
{
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b)
{
return a*b/gcd(a,b);
}
int vis[50];
void solve()
{
memset(vis,0,sizeof(vis));
int n;cin>>n;
ll len = 1,ans_cnt = 0;
for(int i = 0;i < n;i ++) {
cin >> str[i];
len = lcm(len,str[i].length()*1ll);
for(int j = 0;j < str[i].size();j ++){
if(vis[str[i][j]-'a'] == 0) ans_cnt++;
vis[str[i][j]-'a']=1;
}
}
len = len * 2 * n;
int cnt = len;
vector<int> str_p(n+1,0);
string ans_s="";
int p = 0;
while(len--){
ans_s += str[p][str_p[p]];
str_p[p] = (str_p[p] + 1) % (1ll*str[p].size());
p = (p+1)%n;
}
for(int i=0;i<26;i++) vis[i]=0;
int l=0,r=0;
int t_cnt=0;
int ans = 0x3f3f3f3f;
while(true){
while(t_cnt == ans_cnt){
ans = min(ans,r-l);
if(vis[ans_s[l]-'a'] == 1) t_cnt --;
vis[ans_s[l]-'a']--;
l++;
}
if(r == cnt) break;
if(!vis[ans_s[r]-'a']) t_cnt ++;
vis[ans_s[r]-'a']++;
r++;
}
cout<<ans<<endl;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("a.txt", "r", stdin);
freopen("aout.txt", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
solve();
}