题目:
为了找到自己满意的工作,牛牛收集了每种工作的难度和报酬。牛牛选工作的标准是在难度不超过自身能力值的情况下,牛牛选择报酬最高的工作。在牛牛选定了自己的工作后,牛牛的小伙伴们来找牛牛帮忙选工作,牛牛依然使用自己的标准来帮助小伙伴们。牛牛的小伙伴太多了,于是他只好把这个任务交给了你。
输入描述:
每个输入包含一个测试用例。
每个测试用例的第一行包含两个正整数,分别表示工作的数量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)