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'; }