题
为了找到自己满意的工作,牛牛收集了每种工作的难度和报酬。牛牛选工作的标准是在难度不超过自身能力值的情况下,牛牛选择报酬最高的工作。在牛牛选定了自己的工作后,牛牛的小伙伴们来找牛牛帮忙选工作,牛牛依然使用自己的标准来帮助小伙伴们。牛牛的小伙伴太多了,于是他只好把这个任务交给了你。
输入描述
每个输入包含一个测试用例。
每个测试用例的第一行包含两个正整数,分别表示工作的数量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
暴力法
时间复杂度:O(N*M)。
空间复杂度:O(N+M)。
1 #include <iostream> 2 #include <vector> 3 4 using namespace std; 5 6 int main() 7 { 8 //输入数据 9 int N, M; 10 cin >> N >> M; 11 vector<int> difficulty(N), profit(N), ability(M); 12 int i = 0; 13 while (i < N) 14 { 15 cin >> difficulty[i] >> profit[i]; 16 i++; 17 } 18 int j = 0; 19 while (j < M) 20 { 21 cin >> ability[j]; 22 j++; 23 } 24 //解决问题 25 for (const auto Ai : ability) 26 { 27 int maxPay = 0; 28 for (int j = 0; j < N; ++j) 29 { 30 if (Ai >= difficulty[j]) 31 maxPay = max(maxPay, profit[j]); 32 } 33 cout << maxPay << endl; 34 } 35 return 0; 36 }
排序+双指针
思路:工人i能做的工作,能力比他高的工人i+1一定能做,换句话说工人i+1的最大薪酬至少是i的最大薪酬。我们只需要把i的最大薪酬和i+1的另外可以胜任的工作薪酬比较取最大即可。使用双指针来分别定位已经访问过的工作和工人。
时间复杂度:O(N*logN + M*logM)。分别对工作排序时间复杂度我O(N*logN),对工人排序时间复杂度为O(M*logM)。最后的比较时间复杂度为O(M + N),因为每个元素都只遍历1次。
空间复杂度:O(N + M)。
1 #include <iostream> 2 #include <vector> 3 #include <numeric> //for iota() 4 #include <algorithm> // for sort() 5 #include <iterator> //ostream_iterator<T> 6 7 using namespace std; 8 9 int main() 10 { 11 //输入数据 12 int N, M; 13 cin >> N >> M; 14 vector<int> difficulty(N), profit(N), ability(M); 15 int i = 0; 16 while (i < N) 17 { 18 cin >> difficulty[i] >> profit[i]; 19 i++; 20 } 21 i = 0; 22 while (i < M) 23 { 24 cin >> ability[i]; 25 i++; 26 } 27 //解决问题 28 //记录工作难度和工人能力值索引 29 vector<int> difficulty_index(difficulty.size()), ability_index(ability.size()); 30 iota(difficulty_index.begin(), difficulty_index.end(), 0); 31 iota(ability_index.begin(), ability_index.end(), 0); 32 // 排序 33 //O(N*logN) 34 sort(difficulty_index.begin(), difficulty_index.end(), [&] (int a, int b) {return difficulty[a] < difficulty[b]; }); 35 //O(M*logM) 36 sort(ability_index.begin(), ability_index.end(), [&] (int a, int b) {return ability[a] < ability[b]; }); 37 38 vector<int> ans(M, 0); 39 int maxPay = 0; 40 int j = 0; //工作难度指针 41 //O(M + N) 42 for (int i = 0; i < M; ++i) //工人能力指针 43 { 44 while (j < N && difficulty[difficulty_index[j]] <= ability[ability_index[i]]) 45 maxPay = max(maxPay, profit[difficulty_index[j++]]); 46 ans[ability_index[i]] = maxPay; 47 } 48 //输出结果 49 copy(ans.begin(), ans.end(), ostream_iterator<int>(cout, " ")); 50 return 0; 51 }