【每日一题018】腾讯2018春招技术类编程题汇总-5

题目

题目来源
小Q的公司最近接到m个任务, 第i个任务需要xi的时间去完成, 难度等级为yi。
小Q拥有n台机器, 每台机器最长工作时间zi, 机器等级wi。
对于一个任务,它只能交由一台机器来完成, 如果安排给它的机器的最长工作时间小于任务需要的时间, 则不能完成,如果完成这个任务将获得200 * xi + 3 * yi收益。

对于一台机器,它一天只能完成一个任务, 如果它的机器等级小于安排给它的任务难度等级, 则不能完成。

小Q想在今天尽可能的去完成任务, 即完成的任务数量最大。如果有多种安排方案,小Q还想找到收益最大的那个方案。小Q需要你来帮助他计算一下。

思路

依然参考了牛客网大佬的思路:参考博客
主要通过结构体和sort函数,对machine和task进行排序后,进行比较计算。

相关思考

一开始有点疑惑,为什么随着任务i数量的增加,j不是从头开始计算而是从上次的位置j开始,后来明白统一进行了排序后,若该机器能够满足前面任务的时间需求(经过排序后前面任务对时间的需求更大),则必定可以满足后面的机器对时间的需求。
由此,无论是任务还是机器,都不会进行第二次计数,也就对应了题目中的,一个任务只能由一个机器完成,一个机器只能完成一个任务的条件。

代码(C++/牛客)

//安排机器
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int maxn  = 1e5 + 10;
struct node{
	int time,grade;
}machine[maxn],task[maxn]; 
 
int cnt[105];
 
int cmp(node a,node b){
	if(a.time==b.time){
		return a.grade>b.grade;
	}
	return a.time>b.time;
}
 
int main(){
	int numMachine,numTask;
	scanf("%d%d",&numMachine,&numTask);
	for(int i=0;i<numMachine;i++){
		scanf("%d%d",&machine[i].time,&machine[i].grade);
	}
	for(int i=0;i<numTask;i++){
		scanf("%d%d",&task[i].time,&task[i].grade);
	}
	sort(machine,machine+numMachine,cmp);
	sort(task,task+numTask,cmp);
//	for(int i=0;i<numMachine;i++){
//		printf("%d %d\n",e[i].time,e[i].grade);
//	}
//	for(int i=0;i<numTask;i++){
//		printf("%d %d\n",f[i].time,f[i].grade);
//	}
	
	int num = 0;
	LL ans = 0;
	memset(cnt,0,sizeof(cnt));
	int i,j,k;
	for(i=0,j=0;i<numTask;i++){ //对于每个任务而言 
		while(j<numMachine && machine[j].time>=task[i].time){
			cnt[machine[j].grade]++;
			j++;
		}
		for(k=task[i].grade;k<=100;k++){
			if(cnt[k]){
				num++;
				cnt[k]--;
				ans = ans+200*task[i].time + 3*task[i].grade;
				break;
			}
		}
	}
	printf("%d %lld\n",num,ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值