笔试真题 牛牛找工作

题目:

为了找到自己满意的工作,牛牛收集了每种工作的难度和报酬。牛牛选工作的标准是在难度不超过自身能力值的情况下,牛牛选择报酬最高的工作。在牛牛选定了自己的工作后,牛牛的小伙伴们来找牛牛帮忙选工作,牛牛依然使用自己的标准来帮助小伙伴们。牛牛的小伙伴太多了,于是他只好把这个任务交给了你。

输入描述:

每个输入包含一个测试用例。
每个测试用例的第一行包含两个正整数,分别表示工作的数量N(N<=100000)和小伙伴的数量M(M<=100000)。
接下来的N行每行包含两个正整数,分别表示该项工作的难度Di(Di<=1000000000)和报酬Pi(Pi<=1000000000)。
接下来的一行包含M个正整数,分别表示M个小伙伴的能力值Ai(Ai<=1000000000)。
保证不存在两项工作的报酬相同。

输出描述:

对于每个小伙伴,在单独的一行输出一个正整数表示他能得到的最高报酬。一个工作可以被多个人选择。

思考思路:

题目里说明关键的一点:在难度不超过自身能力值的情况下,选择报酬最高的工作,所以我们想储存数据的话,只用储存每个难度里报酬最高的工作就好了。

过程:

1.利用某种方式储存数据,这里java用的是MAP,python可以用字典
2.记录特定难度范围内的最高报酬。
3.难度不超过自身能力值,说明有难度Di<自身能力值Ai,涉及比较的话,最好用排序算法排序。
4.考虑到有多个伙伴,所以记录特定难度范围内的最高报酬是必要的,可以降低时间复杂度。

java代码


import java.util.*;

public class Main {
	public static long findmax(ArrayList<Long> arrayList,long target) {
		long len=arrayList.size();
		long start=0;
		long end =len-1;
		long idx=0;
		while (start<=end) {
			if (start==end) {
				if (arrayList.get((int) start)<target) {return start;}
				else if (arrayList.get((int) start)==target) {return start;}
				else return start-1;
			}
			int mid = (int)((start+end)/2);
			if (arrayList.get(mid)<target) {
				start = mid+1;
			}
			else if (arrayList.get(mid)==target) {
				return mid;
			}
			else {end = mid-1;}
		}
		return start-1;
		
	}
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Map<Long, Long> map = new HashMap<Long, Long>();
        ArrayList<Long> arrayList = new ArrayList<Long>();
        long N=in.nextLong();
        long M=in.nextLong();
        while (in.hasNextLong()) {
        for(int i=0;i<N;++i) {
        	long Di = in.nextLong();
        	long Pi = in.nextLong();
        	if (map.containsKey(Di)){
        		//判断大小
        		if ((Long)map.get(Di)<Pi) {
        			map.remove(Di);
        			map.put(Di,Pi);
        			
        		}
        	}
        	else {arrayList.add(Di);
        		  map.put(Di,Pi);
        	}//key不存在
        }//加载完工作
        Collections.sort(arrayList);
        
        Map<Long, Long> maxMap = new HashMap<Long, Long>();
        for (int k=0;k<arrayList.size();++k) {
        	Long currentDi = arrayList.get(k);
        	if(k==0) {
        		maxMap.put(currentDi,map.get(currentDi));
        	}
        	else {
        		Long lastDi = arrayList.get(k-1);
        		if (maxMap.get(lastDi)<map.get(currentDi)) {
        			maxMap.put(currentDi,map.get(currentDi));
        		}
        		else {
        			maxMap.put(currentDi, maxMap.get(lastDi));
        		}
        	}
        
        }
        for (int k=0;k<M;++k) {
        	long max =0;
        	long Di_person =in.nextLong();
        	//寻找小于等于Di_person且最大的那个Di,二分法吧
        	long idx = findmax(arrayList, Di_person);
        	if(idx<0) {max =0;}
        	else {
        		max = maxMap.get(arrayList.get((int) idx));
        	}
        	System.out.println(max);
        	
        }
        
        }
    }
}

python


import sys
import bisect
lines = sys.stdin.readlines()
N,M = map(int, lines[0].strip().split())
dic = dict()
li = []
for line in lines[1:-1]:
    if not line.strip().split():
        continue
    Di, Pi = map(int, line.strip().split())
    if Di not in dic:
        dic[Di]=Pi
        li.append(Di)
    else:
        if Pi>dic[Di]:
            dic[Di]=Pi
li.sort()
maxmap = dict()
size = len(li)
for i in range(size):
    if i==0:
        maxmap[li[i]]=dic[li[i]]
    else:
        if dic[li[i]]>maxmap[li[i-1]]:
            maxmap[li[i]]=dic[li[i]]
        else:
            maxmap[li[i]]=maxmap[li[i-1]]
Ms = map(int, lines[-1].strip().split())
for i in Ms:
    i = int(i)
    #print('i',i)
    idx =bisect.bisect(li,i)-1
    #print('idx',idx)
    max =0
    if idx<0:
        max =0
    else :
        max = maxmap[li[idx]]
    print(max)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值