NC211592. 重新排列
描述
牛牛有个很喜欢的字符串”puleyaknoi“。
牛牛有T个很长很长的字符串,他很喜欢把字符串中的子串(连续的某段)打乱,并且按照自己的喜好重新排列。
如果牛牛能把一段重新排列出他喜欢的字符串,他就会把这个子串称作:喜欢的子串。
牛牛是个懒人,他不喜欢对太长的子串进行重排,那样他会觉着眼镜很累。
你能帮他求出对于每个字符串,最短的喜欢的子串的长度是多少吗?
如果没有,请输出-1。
输入描述
第一行一个表示数据组数
接下来行每行一个字符串(保证字符串只含小写字母)
输出描述
共T行每行一个答案
示例1
输入:
2 sxpuleyaaknoip konijiwa
输出:
11 -1
说明:
C++14(g++5.4) 解法, 执行用时: 21ms, 内存消耗: 576K, 提交时间: 2020-09-25 21:51:57
#include<bits/stdc++.h> #define For(a,b,c) for(int a=b;a<=c;++a) using namespace std; enum{N=100007}; char const W[]="puleyaknoi"; char S[N]; int n,F[10]; void magic() { scanf("%s",S+1),n=strlen(S+1); For(i,0,9) F[i]=-1; int s=n+1; For(i,1,n) { For(j,0,9) if(S[i]==W[j]) F[j]=i; int x=n+1; For(j,0,9) x=min(x,F[j]); if(x>=0) s=min(s,i-x+1); } if(s==n+1) s=-1; printf("%d\n",s); } int main() { int T; scanf("%d",&T); For(_,1,T) { magic(); } return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 20ms, 内存消耗: 472K, 提交时间: 2020-09-26 12:08:08
#include<cstdio> char a[20]="puleyaknoi",s[100001]; int b[10]; int main() { int T; scanf("%d",&T); while(T--) { scanf("%s",s); int ans=9999999; for(int i=0;i<10;i++) b[i]=-9999999; for(int i=0;s[i];i++) { for(int j=0;j<10;j++) if(s[i]==a[j]) b[j]=i; int lx=i; for(int j=0;j<10;j++) if(b[j]<lx) lx=b[j]; if(i-lx+1<ans) ans=i-lx+1; } if(ans==9999999) ans=-1; printf("%d\n",ans); } }