列表

详情


NC200516. 都说小镇的切糕贵

描述

“一刀建林流泪,两刀马云都得跪。”摆在你面前的一长条切糕,你想尝到切糕里面所有的果仁,什么核桃呀,杏仁呀,巴旦木呀但因为切糕很贵,你要选取一段连续的切糕,使得你能吃到这份切糕里所有的果仁,切记切糕贵,所以要选取最短的长度并且要包含所有的果仁,这里的果仁可以简单的看做a果仁,b果仁,c果仁….,输出能包含所有果仁的最短长度。换句话说出现的果仁都要出现在你所选的区间里面,输出这个区间的最短长度。

输入描述

第一行包含整数n(1≤n≤100 000)——切糕的长度。
第二行包含长度为n的字符串,它由英文字母表中的大写字母和小写字母组成。

输出描述

输出一个整数,表示最小选取的长度。

示例1

输入:

1
A

输出:

1

示例2

输入:

4
qqqE

输出:

2

示例3

输入:

9
bcdddbddc

输出:

3

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 21ms, 内存消耗: 612K, 提交时间: 2019-12-28 15:01:47

#include<bits/stdc++.h>
using namespace std;
int main()
{
    // freopen("ans1.in","r",stdin);
    // freopen("ans1.out","w",stdout);
	string s;
    int n;
    cin>>n;
	cin>>s;
	set<char>ss;
	for(int i=0;i<s.size();i++)
	ss.insert(s[i]);
	int num=ss.size();
	map<char,int>mp;
	int l=0,r=0;
	int ans=0x3f3f3f3f;
	for(int i=0;i<s.size();i++)
	{
		mp[s[i]]++;
		while(mp[s[l]]>1) mp[s[l]]--,l++;
		if(mp.size()==ss.size()) ans=min(ans,i-l+1);
	}
	cout<<ans<<endl;
}

C(clang 3.9) 解法, 执行用时: 3ms, 内存消耗: 380K, 提交时间: 2020-01-03 12:06:21

#include<stdio.h>
#include<string.h>
int a[200];
int main ()
{  int n,i,geshu=0,geshu1=0,j=0;
   char s[100005];
   scanf("%d\n",&n);
   gets(s);
   for(i=0;i<=n-1;i++)
   if(a[s[i]]==0)
    {  a[s[i]]++;
       geshu++;
	}
	int  l=100004;
	memset(a,0,sizeof(a));
	 for(i=0;i<=n-1;i++)
	 {  if(a[s[i]]==0)  geshu1++; 
	    a[s[i]]++;
	    if(geshu1==geshu)
	    {  while(a[s[j]]>1)
		    {a[s[j]]--;j++;}
		  l=l<i-j+1 ? l:i-j+1;
		}
	 }
	 printf("%d",l);
}

C++ 解法, 执行用时: 16ms, 内存消耗: 652K, 提交时间: 2022-03-25 18:04:21

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;string str;
	set<char>s;
	cin>>n>>str;
	int ans=1e9;
	for(int i=0;i<n;i++) s.insert(str[i]);
	int l=0;
	map<char,int>m;
	for(int i=0;i<n;i++)
	{
		 m[str[i]]++;
		 while(m[str[l]]>1){ m[str[l]]--;l++;}
		 if(m.size()==s.size())  ans=min(ans,i-l+1);
	}
	cout<<ans<<'\n';
}

上一题