腾讯2018实习生笔试编程题 三

一、题目描述:

小Q的公司最近接到m个任务,第i个任务需要xi的时间去完成,难度等级为yi。

小Q拥有n台机器,每台机器最长工作时间zi,机器等级wi。

对于一个任务,它只能交由一台机器来完成,如果安排给它的机器的最长工作时间小于任务需要的时间,则不能完成,如果完成这个任务将获得200*xi+3*yi的收益。

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

小Q想在今天尽可能的去完成任务,即完成的任务数量最大。如果有多种安排方案,小Q还想找到收益最大的那个方案。

输入描述:

输入包括N+M+1行,

输入的第一行为两个正整数n和m(1<=n,m<=100000),表示机器的数量和任务的数量。

接下来n行,每行两个整数xi和yi(0

接下来m行,每行两个整数zi和wi(0

输出描述:

输出两个正整数,分别表示最大能完成的任务数量和获取的收益。

示例1:

输入

1 2
100 3
100 2
100 1

输出

1 20006

二、解题思路:贪心求解。

收益只与完成的任务x、y有关,且x、y越大,获得的收益越大,所以要优先完成x更大的任务,若x相等,则要优先完成y大的任务。

为保证上述完成要求,我们可以将任务的x按从大到小排序,若x相同,根据y从大到小排序,排序完成后,再给任务分配机器。

当有多台机器符合x条件,选择y满足条件的最小的wi。

三、代码实现:

c++代码:

#include
#include
#include
#define Max 100010
#define LL long long

using namespace std;

struct A
{
	int x;
	int y;
}t[Max], m[Max];



bool cmp(A a, A b)
{
	if(a.x != b.x)return a.x > b.x;
	return a.y > b.y;
}

int main()
{
	int N, M;
	scanf("%d %d", &N, &M);
	for(int i = 0; i < N; i++)
		scanf("%d %d", &m[i].x, &m[i].y);
	for(int j = 0; j < M; j++)
		scanf("%d %d", &t[j].x, &t[j].y);
	sort(t, t + M, cmp);
	sort(m, m + N, cmp);
		
	/*for(int i = 0; i < N; i++)
		printf("%d %d\n", t[i].x, t[i].y);*/
		
	LL sum = 0;
	int count = 0;
	int mark[Max]={0};
	int j = 0;
	for(int i = 0; i < M; i++)
	{
		//每台机器只能用一次,所以分配下一个任务时,j从上一个任务之后开始考虑,j不用归0
		//由于任务是按从到大小排列的,因此满足上一任务要求的机器一定满足下一任务要求
		while(j < N && m[j].x >= t[i].x)
		{
			mark[m[j].y]++;//机器对应等级加1,表示满足该任务时长下,符合等级要求的可用的机器数
			j++;
		}
		for(int k = t[i].y; k <= 100; k++)//从符合等级要求的等级最低的机器开始分配
		{
			if(mark[k])
			{
				mark[k]--;
				count++;
				sum += (LL)(200 * t[i].x + 3 * t[i].y);
				//printf("sum = %lld\n", sum);
				break;
			}
		}
	}
	printf("%d %lld\n", count, sum);
	
	return 0;
}

Java代码:

import java.util.Arrays;
import java.util.Scanner;
class A implements Comparable{
	int x;
	int y;
	public int compareTo(A o) {
        // TODO Auto-generated method stub  	
        if(this.x>o.x)
            return -1;//返回-1表示当前对象在前,即由高到底排序  ;return 1则为由低到高排
        else if(this.xo.y)  
                return -1;//由高到低排序  
            else if(this.y)对于参数(A[])不适用
//        for(i=0;i

知识点:

1.A[] machine = new A[Max];语句之后,若想对machine[]中的变量进行赋值,需要先machine[i] = new A();

2.对类类型数组进行排序,要实现Comparable接口的compareTo方法

3.Arrays.copyOfRange(int[] original,int from,int to);方法从一个数组中截取一定长度的元素放到新数组中

你可能感兴趣的:(LintCode)