jzoj100046. 收集卡片

本文介绍了一个关于连续订阅杂志收集不同卡片种类的问题,通过使用双指针技术来寻找最少订阅期数,以收集到所有种类的卡片。算法通过不断调整左右指针的位置,检查是否收集到了所有种类的卡片,最终确定最小的订阅期数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

唉,本来都不想写这一题的。。。

Description
Star 计划订购一本将要发行的周刊杂志,但他可不是为了读书,而是—— 集卡。 已知杂志将要发行 N 周(也就是 N
期),每期都会附赠一张卡片。Star 通 过种种途径,了解到 N 期杂志附赠的卡片种类。Star 只想订购连续的若干期,
并在这些期内收集所有可能出现的种类的卡片。现在他想知道,他最少需要订 购多少期。

Input
一行一个整数 N; 第二行一个长度为 N 的字符串,由大写或小写字母组成,第 i 个字符表示 第 i
期附赠的卡片种类,每种字符(区分大小写)表示一种卡片。

Output
输出一行一个整数,表示 Star 最少订购的期数。

Sample Input
8 acbbbcca

Sample Output
3

这题两个指针不停地跳即可。
上标:

#include<cstdio>
#include<algorithm>
using namespace std;
int n,a[500010],l=1,r=1,now[500010],ans;
bool bz[500010];char c;

bool check()
{
	for (int i=1;i<=52;i++)
		if (bz[i]==1 && !now[i]) return 0;
	return 1;
}

int main()
{
	scanf("%d\n",&n);
	for (int i=1;i<=n;i++)
		if ((c=getchar())>='a') a[i]=c-'a'+1,bz[a[i]]=1;
		else a[i]=c-'A'+27,bz[a[i]]=1;
	now[a[1]]++;while (!check()) now[a[++r]]++;ans=r;
	while (l<=n)
	{
		now[a[l++]]--;
		while (now[a[l]]>1) now[a[l++]]--;
		while (!check() && r<=n) now[a[++r]]++;
		if (r>n) break;
		ans=min(ans,r-l+1);
	}
	printf("%d\n",ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值