CF898D:贪心

CF898D

这是一道很好的题目,我思考了很久,终于搞透了。思维很好,代码很简洁。

题意:

  • 有n个闹钟,会在指定的时间内响。
  • 此人会在连续m个时间内,至少有k个时钟响时醒来。
  • 关掉最少的闹钟,使此人能够睡一个好觉。

题解:

  • 容器:排序+双端队列。
  • 贪心:如果满足醒来的条件,每次优先关掉的是后面的闹钟,因为后面的会影响更后面的。
  • 每次控制闹钟的个数为k个。举个栗子,k = 2,如果队列里此时进入a和b,并且时间差≤m,那么关掉闹钟b。如果下次再进来一个闹钟c,a和c的时间差≤m,那么关掉c。否则从队列里去掉a,因为后面进入队列的和a的时间差一定>m。

代码:

#include <bits/stdc++.h>
using namespace std;
int const N = 200000 + 10;
int a[N],n,m,k;
deque<int>q;
int main(){
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++)	scanf("%d",&a[i]);
	sort(a+1,a+1+n);
	int ans = 0;
	for(int i=1;i<=n;i++){
		q.push_front(a[i]);
		if(q.size() == k){
			if(q.front() - q.back() + 1 <= m){
				q.pop_front();
				ans++;
			}else	q.pop_back();
		}
	}
	printf("%d\n",ans);
}

 

posted @ 2019-02-28 10:56  月光下の魔术师  阅读(9)  评论(0)    收藏  举报