蓝桥每日真题之负载均衡

Posted MangataTS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥每日真题之负载均衡相关的知识,希望对你有一定的参考价值。

题目来源

2021年蓝桥省赛第二场I题

题目链接:http://acm.mangata.ltd/p/P1480

考点

优先队列、模拟

视频讲解

视频连接:https://www.bilibili.com/video/BV1ST4y117fs

思路

因为有n台计算机,所以我们可以开一个数组V,V[i]表示第i台机器的算力大小,考虑到一个任务是在第a[i]时刻开始到a[i]+c[i]结束的,所以我们得想办法记录下来,但是都记录吗?咱们NO,其实每当一个任务来临得时候,我们只需要看看指定的这一台计算机有哪些任务以及结束了,由于a数组(时间)是严格升序的,我们会发现只需要记录下结束的时间即可,我们每次有一个任务来临我们就把之前任务的算力释放出来,那么我们应该从最早结束的任务开始查看,如果以及结束了,那么我们就释放,然后看下一个任务,如果没有结束,那么后面的任务都不会在当前时刻结束,然后我们就能计算出当前还剩下多少算力,然后和当前这个任务进行判断如果能执行,那么继续放在我们的这个任务序列中

现在的问题就变成了,我们怎么维护每个计算机的任务序列,我们很容易能想到堆,用一个小顶堆来维护,因为我们的任务结束时间需要升序,STL已经帮我们实现好了也就是priority_queue即优先队列,然后我们每个任务除了结束时间,我们还应该知道这个任务的算力,因为我们要释放算力,这里我们可以直接使用pair<int,int>或者使用自定义结构体,但是结构体需要自己写重载,所以我这里推荐大家使用pair。那么我们就来写代码吧!

代码

#include<bits/stdc++.h>
using namespace std;
//----------------自定义部分----------------
#define ll long long
#define mod 1000000009
#define endl "\\n"
#define PII pair<int,int>

int dx[4]=0,-1,0,1,dy[4]=-1,0,1,0;

ll ksm(ll a,ll b) 
	ll ans = 1;
	for(;b;b>>=1LL) 
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	
	return ans;


ll lowbit(ll x)return -x & x;

const int N = 2e5+10;
//----------------自定义部分----------------
int n,m,q,a,b,c,d,V[N];
priority_queue<PII,vector<PII>,greater<PII> > que[N];//维护n台电脑的小顶堆

int main()

	cin>>n>>m;
	for(int i = 1;i <= n; ++i) cin>>V[i];//输出算力 
	for(int i = 0;i < m; ++i) 
		cin>>a>>b>>c>>d;
		while(que[b].size())
			int ed = que[b].top().first;//当前最先结束的任务的时间
			int kk = que[b].top().second;//当前最先结束的任务的算力
			if(ed > a) break;//如果当前任务结束时间大于当前时间,后面的任务肯定都大于
			V[b] += kk;
			que[b].pop();
		
		if(V[b] < d)//如果当前的算力不足,那么直接输出-1
			cout<<"-1"<<endl;
		
		else//如果当前的算力充足,那么就把这个任务放入b计算机的队列中
			que[b].push(a+c,d);
			V[b] -= d;
			cout<<V[b]<<endl;
		
	
	
	return 0;

/*
2 6
5 5
1 1 5 3
2 2 2 6
3 1 2 3
4 1 6 1
5 1 3 3
6 1 3 4
*/

以上是关于蓝桥每日真题之负载均衡的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥杯每日真题之直线

蓝桥每日真题之123

蓝桥每日真题之完全日期

蓝桥杯每日真题之货物摆放

蓝桥每日真题之小朋友排队

蓝桥每日真题之完全平方数