CF898D Alarm Clock题解

原题传送门

前言

此题甚水,但蒟蒻考试时却没有做出,罪过罪过!

分析

题目要求我们在 [ i , i + m ] [i,i + m] [i,i+m] 的区间内,闹钟数量不超过 k k k 个。如果直接枚举第 i i i 种情况,复杂度为 O ( n × m ) O(n \times m) O(n×m),显然是会超时的。

此时使用贪心思想,当我们在挨个枚举闹钟数量的时候,可以开个队列 q q q 记录闹钟的数量。记 r e s res res 为拔掉的个数,当需要拔的时候, a i a_{i} ai 直接出队并让 r e s res res 记录一下即可。但是需要注意,为了让队列只扫 1 1 1 遍,所以先排序,保证 a i a_{i} ai 单调递增。

时间复杂度: O ( n log ⁡ n ) O(n \log n) O(nlogn)

AC code

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5;
int n,m,k,res;
int a[maxn];
queue<int> q;//见思路
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin>>n>>m>>k;//输入
	for(int i = 1;i <= n;i++)
	{
		cin>>a[i];
	}
	sort(a + 1,a + 1 + n);//先排序
	for(int i = 1;i <= n;i++)
	{
		while(!q.empty() && a[i] - q.front() >= m)//清空队列
		{
			q.pop();
		}
		if(q.size() >= k - 1)//满足情况
		{
			res++;
		}
		else//否则再次入队
		{
			q.push(a[i]);
		}
	}
	cout<<res<<endl;//输出
	return 0;//完结,撒花
}

AC submissions

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值