Educational Codeforces Round 61 (Rated for Div. 2) D. Stressful Training //二分

14 篇文章 0 订阅
10 篇文章 0 订阅

https://codeforces.com/contest/1132/problem/D

 题题意是有n台笔记本,要同时使用k个时间,每个时间可以给一台电脑充电x电量,求最小的x使得n台笔记本可以度过k时间。

显然 x越大越好,如果有答案,一定在某个值刚好成立,线性问题,直接二分x。

首先想法是维护一个还能使用时间最小的电脑(a[i]/b[i])最小,然后模拟,贪心的给能存活时间最短的电脑优先充电。

坑的地方是,multiset不能过(直接卡到22组,预先sort卡到27组),

优先队列或线段树(维护最小值)可以过。 (???)

https://blog.csdn.net/ccsu_cat/article/details/88310531(线段树也几乎是卡死)

贴优先队列代码(小心数据范围可能有爆的地方)

复杂度(O(K*log(ans)*log(n))

#include<bits/stdc++.h>
using namespace std;
#define LL long long
struct no{
	LL a;
	LL b;
	LL c;
}lap[200005];
bool operator<(const no &x,const no &y){
	return x.c>y.c;
}
int n,k;
bool check(LL mid){
	priority_queue<no> q;
	for(int i=1;i<=n;i++) q.push(lap[i]);
	for(LL i=1;i<k;i++){
		no cur=q.top();q.pop();
		cur.a=cur.a+mid;
		cur.c=cur.a/cur.b;
		q.push(cur);
		if(q.top().c<i) return 0;
	}
	return 1;
}
LL binary(){
	LL l=0,r=1e13;
	LL ans=LLONG_MAX;
	while(l<=r){
		LL mid=(l+r)/2;
		if(check(mid)){
			ans=mid;
			r=mid-1;
		} 
		else  l=mid+1;
	}
	return ans;
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n>>k;
	for(int i=1;i<=n;i++) cin>>lap[i].a;
	for(int i=1;i<=n;i++) {
		cin>>lap[i].b; 
		lap[i].c=lap[i].a/lap[i].b;
	}
	LL ans=binary();
	if(ans==LLONG_MAX) cout<<-1;
	else cout<< ans; 
	return 0;
} 

题解有一种复杂度(O(K*log(ans))的做法

用vector维护小于生命期小于k的电脑的编号。 v[i] 里面放 当前生命期为i天的 电脑编号,然后模拟一遍写check。

 By RSHS, contest: Educational Codeforces Round 61 (Rated for Div. 2), problem: (D) Stressful Training, Accepted, #

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int maxn=2*1e5+5; 
int n,k;
LL a[maxn],b[maxn];
vector<int> v[maxn];
bool check(LL mid){
	for(int i=0;i<=k;i++) v[i].clear();
	LL cnt[maxn];
	for(int i=1;i<=n;i++){
		LL x=a[i]/b[i];
		if(x>=k) continue;
		cnt[i]=a[i]%b[i];
		v[x].push_back(i);
	}
	int p=0;
	for(LL i=0;i<k;i++){
		while(v[p].size()==0&&p<k)
			p++;
		if(p==k) break;
		int u=v[p].back();
		v[p].pop_back();
		LL newa=p*b[u]+cnt[u]+mid;
		LL uu=newa/b[u];
		if(uu<k){
			v[uu].push_back(u);
			cnt[u]=newa%b[u];
		}
		if(v[i].size()!=0) return false;
		
	}
	return true;
}
LL binary(){
	LL l=0,r=1e15;
	LL ans=LLONG_MAX;
	while(l<=r){
		LL mid=(l+r)/2;
		if(check(mid)){
			ans=mid;
			r=mid-1;
		} 
		else  l=mid+1;
	}
	return ans;
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n>>k;k--;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) cin>>b[i];
	LL ans=binary();
	if(ans==LLONG_MAX) cout<<-1;
	else cout<< ans; 
	return 0;
} 

优先队列(几乎卡死)

 vector模拟优化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"educational codeforces round 103 (rated for div. 2)"是一个Codeforces平台上的教育性比赛,专为2级选手设计评级。以下是有关该比赛的回答。 "educational codeforces round 103 (rated for div. 2)"是一场Codeforces平台上的教育性比赛。Codeforces是一个为程序员提供竞赛和评级的在线平台。这场比赛是专为2级选手设计的,这意味着它适合那些在算法和数据结构方面已经积累了一定经验的选手参与。 与其他Codeforces比赛一样,这场比赛将由多个问题组成,选手需要根据给定的问题描述和测试用例,编写程序来解决这些问题。比赛的时限通常有两到三个小时,选手需要在规定的时间内提交他们的解答。他们的程序将在Codeforces的在线评测系统上运行,并根据程序的正确性和效率进行评分。 该比赛被称为"educational",意味着比赛的目的是教育性的,而不是针对专业的竞争性。这种教育性比赛为选手提供了一个学习和提高他们编程技能的机会。即使选手没有在比赛中获得很高的排名,他们也可以从其他选手的解决方案中学习,并通过参与讨论获得更多的知识。 参加"educational codeforces round 103 (rated for div. 2)"对于2级选手来说是很有意义的。他们可以通过解决难度适中的问题来测试和巩固他们的算法和编程技巧。另外,这种比赛对于提高解决问题能力,锻炼思维和提高团队合作能力也是非常有帮助的。 总的来说,"educational codeforces round 103 (rated for div. 2)"是一场为2级选手设计的教育性比赛,旨在提高他们的编程技能和算法能力。参与这样的比赛可以为选手提供学习和进步的机会,同时也促进了编程社区的交流与合作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值