网易2018---牛牛找工作

牛牛找工作

时间限制:2秒

空间限制:65536K

为了找到自己满意的工作,牛牛收集了每种工作的难度和报酬。牛牛选工作的标准是在难度不超过自身能力值的情况下,牛牛选择报酬最高的工作。在牛牛选定了自己的工作后,牛牛的小伙伴们来找牛牛帮忙选工作,牛牛依然使用自己的标准来帮助小伙伴们。牛牛的小伙伴太多了,于是他只好把这个任务交给了你。 
输入描述:
每个输入包含一个测试用例。
每个测试用例的第一行包含两个正整数,分别表示工作的数量N(N<=100000)和小伙伴的数量M(M<=100000)。
接下来的N行每行包含两个正整数,分别表示该项工作的难度Di(Di<=1000000000)和报酬Pi(Pi<=1000000000)。
接下来的一行包含M个正整数,分别表示M个小伙伴的能力值Ai(Ai<=1000000000)。
保证不存在两项工作的报酬相同。


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

输入例子1:
3 3 
1 100 
10 1000 
1000000000 1001 
9 10 1000000000

输出例子1:
100 
1000 
1001

法一(借鉴):用map存储工作能力和报酬的对应关系,不仅存储所有工作的,而且也存储每个小伙伴的工作能力和报酬(为0),这样在后面计算的时候不用两层for循环,而使用一层for循环就可以搞定,
因为不需要判断小伙伴的能力值和工作能力值的大小关系,只需要计算,到目前的能力值为止,所能获得的最大报酬数,有种dp的味道,用ma保存历史最大报酬数,然后再更新到map中即可。o(nlgn)。代码如下:
 1 public class MainCorrect {
 2 
 3     public static void main(String[] args) {
 4         //划重点!!!此题坑点:输入中间有空行,所以用BuffferedReader会更麻烦,所以选择用Scanner
 5         Scanner sc = new Scanner(System.in);
 6         int n = sc.nextInt();
 7         int m = sc.nextInt();
 8         //保存所有工作的键值对,即<工作能力,报酬>,而且也保存每个小伙伴的能力值键值对,其报酬为0
 9         Map<Integer, Integer> map = new HashMap<Integer, Integer>();
10         //保存所有工作的能力值以及要计算的每个小伙伴的能力值
11         int[] ai = new int[m + n];
12         for(int i = 0; i < n; i++) {
13             int di = sc.nextInt();
14             ai[i] = di;
15             int pi = sc.nextInt();
16             map.put(di, pi);
17         }
18         //保存要计算的每个小伙伴的能力值
19         int[] bi = new int[m];
20         for(int i = 0; i < m; i++) {
21             ai[i + n] = sc.nextInt();
22             bi[i] = ai[i + n];
23             if(!map.containsKey(ai[i + n])) {
24                 map.put(ai[i + n], 0);
25             }
26         }
27         //对能力值进行排序
28         Arrays.sort(ai);
29         //保存到目前的能力值为止,所能获得的最大报酬,有种dp的味道
30         int ma = 0;
31         for(int i = 0; i < m + n; i++) {
32             //每次都更新当前能力值所对应的最大报酬,由于ma是保存的<=当前能力值所能获得的最大报酬,所以可行
33             ma = Math.max(ma, map.get(ai[i]));
34             map.put(ai[i], ma);
35         }
36         //遍历每个小伙伴的能力值,从map中获取到其最大报酬(在上面的for循环中已经更新到了)
37         for(int i = 0; i < m; i++) {
38             System.out.println(map.get(bi[i]));
39         }
40     }
41 
42 }
View Code

法二:两层for循环,先排序,后逐一进行比较判断。o(n^2)。当然超时,仅通过40%。代码如下:

 1 public class Main {
 2 
 3     //用一个类来记录工作能力和报酬的对应关系,其实可以用map实现的
 4     static class Job implements Comparable<Job>{
 5         int di, pi;
 6         public Job(int di, int pi) {
 7             this.di = di;
 8             this.pi = pi;
 9         }
10         //按工作能力值进行排序
11         public int compareTo(Job job) {
12             return this.di - job.di;
13         }
14     }
15     
16     public static void main(String[] args) throws IOException {
17         Scanner sc = new Scanner(System.in);
18         int n = sc.nextInt();
19         int m = sc.nextInt();
20         Job[] jobs = new Job[n];
21         for(int i = 0; i < n; i++) {
22             int di = sc.nextInt();
23             int pi = sc.nextInt();
24             jobs[i] = new Job(di, pi);
25         }
26         //对工作能力进行排序
27         Arrays.sort(jobs);
28         int[] ai = new int[m];
29         for(int i = 0; i < m; i++) {
30             ai[i] = sc.nextInt();
31         }
32         //逐一计算每个小伙伴,在其工作能力之内所能获得的最大报酬
33         for(int i = 0; i < m; i++) {
34             int j = 0;
35             int cnt = 0;
36             while(j < n && jobs[j].di <= ai[i]) {
37                 if(cnt < jobs[j].pi) {
38                     cnt = jobs[j].pi;
39                 }
40                 j++;
41             }
42             System.out.println(cnt);
43         }
44     }
45 
46 }
View Code
原文地址:https://www.cnblogs.com/cing/p/8674813.html