2018.09.16 codeforces1041C. Coffee Break(双端队列)

本文分享了一个关于竞赛编程中处理队列问题的有效算法。通过实例解析,阐述了如何利用特定的数据结构和排序技巧,实现快速的队列元素插入和检索,以解决复杂的时间序列问题。

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

传送门
真心sb题啊。
考场上最开始看成了一道写过的原题。。。
仔细想了一会发现看错了。
其实就是一个sb队列。
每次插入到队首去就行了。
代码:

#include<bits/stdc++.h>
#define N 200005
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
int n,m,d,q[N],ans[N],tot=0,hd,tl;
struct Node{int v,id;}a[N];
inline bool cmp(Node a,Node b){return a.v<b.v;}
int main(){
	n=read(),m=read(),d=read();
	for(int i=1;i<=n;++i)a[i].v=read(),a[i].id=i;
	sort(a+1,a+n+1,cmp);
	hd=1,tl=0;
	q[++tl]=1,ans[a[1].id]=++tot;
	for(int i=2;i<=n;++i){
		if(a[i].v-d-1>=a[q[hd]].v)ans[a[i].id]=ans[a[q[hd]].id],++hd;
		else ans[a[i].id]=++tot;
		q[++tl]=i;
	}
	cout<<tot<<'\n';
	for(int i=1;i<=n;++i)cout<<ans[i]<<' ';
	return 0;
}
### Codeforces Coffee Break 问题解析 #### 题目描述 在一个场景中,某人计划在一段时间内喝 `n` 杯咖啡,每杯咖啡有一个特定的饮用时间点(以分钟为单位)。为了健康考虑,在同一天内任意两杯咖啡之间的最小间隔应不少于 `d` 分钟。目标是计算完成所有咖啡饮用所需的最少天数,并指定每一天具体饮用了哪些咖啡。 #### 解决方案概述 通过分析不同时间段内的可用间隙来安排每日的最大可能饮品数量。此过程可以通过多种方式实现,其中一种高效的方法涉及使用二分查找配合数据结构如集合(set)来进行优化处理[^1]。 对于每一个给定的时间戳 t_i ,算法试图找到最早能够容纳该次休息而不违反 d 分钟约束条件的日子 r_j 。一旦找到了合适的位置,则更新对应的日期并继续下一个请求直到全部分配完毕。 ```cpp #include <bits/stdc++.h> using namespace std; int main() { int n, m, d; cin >> n >> m >> d; // 输入参数 vector<int> times(n); for(auto& time : times){ cin>>time; } set<pair<int,int>> days; for(int i=0;i<n;++i){ auto it = days.lower_bound({times[i]-d+1,-1}); if(it!=days.begin()){ --it; cout<<(++(*it).second)<<' '; days.erase(it); }else{ cout<<1<<' '; } days.insert({times[i],*days.rbegin().second+1}); } } ``` 上述代码实现了基于输入时间和间隔限制的有效调度策略。它利用了 STL 中的 `set` 容器及其成员函数 `lower_bound()` 方法来快速定位满足条件的最佳位置[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值