列表

详情


NC211592. 重新排列

描述

牛牛有个很喜欢的字符串”puleyaknoi“。

牛牛有T个很长很长的字符串,他很喜欢把字符串中的子串(连续的某段)打乱,并且按照自己的喜好重新排列。

如果牛牛能把一段重新排列出他喜欢的字符串,他就会把这个子串称作:喜欢的子串。

牛牛是个懒人,他不喜欢对太长的子串进行重排,那样他会觉着眼镜很累。

你能帮他求出对于每个字符串,最短的喜欢的子串的长度是多少吗?

如果没有,请输出-1。

输入描述

第一行一个表示数据组数

接下来行每行一个字符串(保证字符串只含小写字母)

输出描述

共T行每行一个答案

示例1

输入:

2
sxpuleyaaknoip
konijiwa

输出:

11
-1

说明:

sxpuleyaaknoip中puleyaaknoi可以重排成puleyaknoia,其中包含有puleyaknoi。
konijiwa不能重新排列出puleyaknoi,所以是-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);
	}
}

上一题