比赛的时候连题意都没看懂,雀氏菜。
题目
题意理解以后,就转换成了求一个字符串s中包含涵盖指定字母集的最短子串的长度的题。比如在abbcde中求abc的最短子串,abbc。
首先求出最小公倍数,然后通过输入的字符串求出字符串s。他是一个无限循环的字符串的循环节。
所以要求最短只要两个s拼接在一起,就转变成了上述问题。上述问题可以采用双指针解决。
l = 0,r = 0.
r右移,直到合法。
l左移,直到不合法。
在过程中维护r-l的最小值即可。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<complex>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<unordered_map>
#include<list>
#include<set>
#include<queue>
#include<stack>
#define OldTomato ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define p_ priority_queue
// round() 四舍五入 ceil() 向上取整 floor() 向下取整
// lower_bound(a.begin(),a.end(),tmp,greater<ll>()) 第一个小于等于的
// #define int long long //QAQ
using namespace std;
typedef complex<double> CP;
typedef pair<int,int> PII;
typedef long long ll;
// typedef __int128 it;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const ll inf = 1e18;
const int N = 2e5+10;
const int M = 1e6+10;
const int mod = 1e9+7;
const double eps = 1e-6;
inline int lowbit(int x){ return x&(-x);}
template<typename T>void write(T x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
#define int long long
int n,m,k,T;
string ss[102];
int vis[30];
int cnt[30];
int a[102];
int idx[102];
int gcd(int a,int b)
{
if(b==0) return a;
return gcd(b,a%b);
}
void solve()
{
mem(vis,0);
mem(idx,0);
mem(cnt,0);
cin>>n;
int tmp = -1;
for(int i=1;i<=n;++i)
{
cin>>ss[i];
a[i] = ss[i].length();
for(int j=0;j<ss[i].length();++j) vis[ss[i][j]-'a'] = 1;
if(tmp == -1) tmp = a[i];
else tmp = tmp/gcd(tmp,a[i]) * a[i];
}
string s = "";
int now = 1;
for(int k=1;k<=tmp*n;++k)
{
s += ss[now][idx[now]];
idx[now] = (idx[now] + 1) % a[now];
now ++ ; if(now == n+1) now = 1;
}
s += s;
int all = 0;
for(int i=0;i<26;++i) if(vis[i]) all ++ ; //所有种类的字母
int len = s.length();
// cout<<s.length()<<" "<<len<<endl;
int l = 0,r = 0;
now = 0;
int ans = 1e12;
while(l < len && r < len)
{
if(now < all)
{
cnt[s[r]-'a'] ++ ;
if(cnt[s[r]-'a'] == 1) now ++ ;
r ++ ;
}
else
{
ans = min(ans,r-l);
if(ans <= all)
{
write(ans); puts(""); return ;
}
cnt[s[l]-'a'] -- ;
if(cnt[s[l]-'a'] == 0) now -- ;
l ++ ;
}
}
write(ans); puts("");
}
signed main(void)
{
// T = 1;
OldTomato; cin>>T;
// read(T);
while(T--)
{
solve();
}
return 0;
}