codeforces 834B The Festive Evening

本文详细解析 CodeForces 平台上的 834B 题目,通过记录每个人进入各门的时间来确定所需的最少守卫数量,确保每扇开启的门都有守卫。采用了一种类似于火车座位分配问题的解决方法,通过记录门的开启与关闭时间,最终求得最大守卫需求。

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

传送门:codeforces 834B



题目大意:

有 A~Z 共26扇门,有 n 个人要依次从指定的门进入,每扇门在该门进入的第一个人之前开启,在该门进入的最后一人进入后关闭,之间一直开着,问有 k 个守卫是否可以保证每一时刻每扇开着的门都有守卫看守。



思路:

找到每扇门第一个和最后一个人进入的时间,解法类似于坐火车选坐车区间,问火车最少需要准备多少个座位的题。这种题的一种解法是将每扇门的开始时间对应的点设为 1,结束时间对应的点设为 -1,其他点为 0,然后扫描一遍将这些值相加,取最大值。


但是这样会出现一个问题,如 ABCBA 这组样例,最少需要 3 个守卫,但是 C 是只有一个,这时候可以开两倍的空间,对单个字母特殊处理即可。



代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
using namespace std;

int vis[2000010];

int main()
{
	int i,n,k,f,sz,ans,num;
	char s[1000010];
	vector<int> pos[28]; //保存每扇门人经过的时间 
	while(~scanf("%d%d",&n,&k))
	{
		scanf("%s",s);
		memset(vis,0,sizeof(vis));
		for(i=0;i<=26;i++) pos[i].clear();
		for(i=0;i<n;i++) //将每个人放入对应的门中 
			pos[s[i]-'A'].push_back(i);
		f=0;
		for(i=0;i<=26;i++)
		{ //扫描每个门 
			sz=pos[i].size();
			if(sz==1)
			{ //如果该门只有一个人经过 
				f=1;
				vis[pos[i][0]*2]=1;  //开始点设为 1 
				vis[pos[i][0]*2+1]=-1; //结束点设为 -1 
			}
			if(sz>1)
			{
				vis[pos[i][0]*2]=1; //开始点设为 1 
				vis[pos[i][sz-1]*2]=-1; //结束点设为 -1
			}
		}	
		num=0;
		ans=f;
		for(i=0;i<n*2;i++)
		{ //扫描一遍取最大值 
			num+=vis[i];
			if(num>ans) ans=num;
		}
	//	printf("ans=%d\n",ans);
		if(ans>k) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值