打卡信奥刷题(1632)用C++实现信奥 P7544 [COCI 2019/2020 #4] Nivelle

P7544 [COCI 2019/2020 #4] Nivelle

题目描述

Bojan 看到了 n n n 个可爱的能吃的毛绒玩具摆在商店的货架上。从序号 1 1 1 摆到 n n n。每个毛绒玩具都有 26 26 26 中不同的颜色。每种颜色用英文字母 a . . . z a...z a...z 表示。
对于任何一套玩具,我们都可以把它的颜色定义为一套玩具中不同颜色的玩具数量除以一套玩具的总数。
Bojan 想吃这些玩具,但 Bojan 不喜欢有太多的颜色,所以请你帮助 Bojan 找到一个连续的子序列的玩具,使其色彩数尽可能的少。

输入格式

第一行包含一个正整数 n n n,表示玩具的个数。
第二行包含长度为 n n n 的字符串 S S S,第 i i i 个字符表示架子上的第 i i i 个玩具的颜色。

输出格式

输出只有一行,包含两个整数 l , r l,r l,r,表示所求连续子序列的左端点及右端点。
如果存在多个具有相同颜色数量且颜色最少的连续子序列,则输出任意一个子序列。

输入输出样例 #1

输入 #1

4
hoin

输出 #1

1 4

输入输出样例 #2

输入 #2

7
nivelle

输出 #2

4 7

输入输出样例 #3

输入 #3

6
ananas

输出 #3

1 5

说明/提示

数据范围及约定

本题采用多测试点捆绑测试,共有 5 个子任务。

  • Subtask 1(7 points): 1 ≤ n ≤ 100 1 \leq n \leq 100 1n100
  • Subtask 2(17 points): 1 ≤ n ≤ 2 × 1 0 3 1 \leq n \leq 2 \times 10^3 1n2×103
  • Subtask 3(13 points):字符串 S S S 中只有两个字符 a , b a,b a,b(你可以理解为所有玩具中只有两种颜色)。
  • Subtask 4(25 points):字符串 S S S 中只有五个字符 a , b , c , d , e a,b,c,d,e a,b,c,d,e(你可以理解为所有玩具中只有五种颜色)。
  • Subtask 5(48 points):无特别限制。

对于全部的测试点,保证 1 ≤ n ≤ 1 0 5 , 1 ≤ l ≤ r ≤ n 1 \leq n \leq 10^5,1 \leq l \leq r \leq n 1n1051lrn

【提示与帮助】

题目译自 COCI 2019/2020 CONTEST #4 T5 Nivelle

在 COCI 中,本题分值为 110 110 110 分。

C++实现

#include<bits/stdc++.h>
using namespace std;
string s;
int cnt[26];//双指针使用的,记录每个字母出现的次数。 
int main(){
	int n,ansl=1,ansr=1,ans=1;
	cin>>n>>s;
	s=' '+s;//下标从1开始,方便计算。 
	for(int k=1;k<=26;k++){
		memset(cnt,0,sizeof(cnt));//清空数组。 
		int c=0,Max=0,Maxi,Maxj;
		for(int i=1,j=1;i<=n&&j<=n;j++){//双指针。 
			cnt[s[j]-'a']++;
			if(cnt[s[j]-'a']==1)c++;
			for(;c>k;i++){
				cnt[s[i]-'a']--;
				if(cnt[s[i]-'a']==0)c--;
			}
			if(j-i+1>Max)Max=j-i+1,Maxi=i,Maxj=j;
		}
		int ansh=ansr-ansl+1;//答案的长度。
		//检查是否更新。 
		if(k*ansh<ans*Max)ans=k,ansl=Maxi,ansr=Maxj;//如果比正确答案小,显然需要更新。 
		if(k*ansh==ans*Max&&Maxj<ansr)ans=k,ansl=Maxi,ansr=Maxj;//如果和正确答案相等,比较区间终点。 
	}
	cout<<ansl<<" "<<ansr;//输出。 
	return 0;//完结撒花! 
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值