当前位置:   article > 正文

AcWing周赛 72 场 && LeetCode单周赛 314 场 总结

AcWing周赛 72 场 && LeetCode单周赛 314 场 总结

一、LeetCode单周赛 314 场

1、6200.处理用时最长的那个任务的员工

(1)原题链接:力扣https://leetcode.cn/problems/the-employee-that-worked-on-the-longest-task/

(2)解题思路:

        1、用pair数组保存每个id以及对应的任务的完成时间。

        2、按完成时间所花费的大小顺序排序。

        3、遍历数组,找到时间的最大值,若存在相同值,返回id较小的即可。

(3)参考代码:

  1. class Solution {
  2. public:
  3. int hardestWorker(int n, vector<vector<int>>& logs) {
  4. vector<pair<int, int>> a;
  5. a.push_back({logs[0][1], logs[0][0]});
  6. for(int i = 1; i < logs.size(); i ++ ) {
  7. int t = logs[i][1] - logs[i - 1][1];
  8. a.push_back({t, logs[i][0]});
  9. }
  10. sort(a.begin(), a.end());
  11. int res = 0;
  12. for(int i = a.size() - 1; i > 0; i --) {
  13. if(a[i].first > a[i - 1].first) {
  14. res = a[i].second;
  15. break;
  16. }
  17. if(a[i].first == a[i - 1].first) {
  18. res = min(a[i].second, a[i - 1].second);
  19. }
  20. }
  21. return res;
  22. }
  23. };

2、6201.找出前缀异或的原始数组

(1)原题链接:力扣https://leetcode.cn/problems/find-the-original-array-of-prefix-xor/

(2)解题思路:

        这题就是前缀和的逆运算。具体思路如下:

(3)参考代码:

  1. class Solution {
  2. public:
  3. vector<int> findArray(vector<int>& pref) {
  4. int n = pref.size();
  5. vector<int> res(n);
  6. res[0] = pref[0];
  7. for (int i = 1; i < n; i ++ )
  8. res[i] = pref[i] ^ pref[i - 1];
  9. return res;
  10. }
  11. };

3、6202.使用机器人打印字典序最小的字符串

(1)原题链接:力扣https://leetcode.cn/problems/using-a-robot-to-print-the-lexicographically-smallest-string/

(2)解题思路:

        1、遍历s串,找到所有的a,然后加入到t中,若加入时当前字母是 'a' 则直接输出,若不是则暂时加入到t中。

        2、再遍历一遍s串,找到所有的b,但是要先将t中小于等于b的字典序的字母输出,当遍历到t中的某个字母大于b了,则开始类似的重复第一步。以此类推,处理26个字母。

        3、最后再将t中剩余的元素输出即可。

(3)参考代码:

  1. class Solution {
  2. public:
  3. string robotWithString(string s) {
  4. string res, t;
  5. //保存每个字母最后出现的位置
  6. vector<int> pos(26, -1);
  7. for(int i = 0; i < s.size(); i ++ )
  8. pos[s[i] - 'a'] = i;
  9. for(int i = 0, k = 0; i < 26 && k < s.size(); i ++ ) {
  10. char c = i + 'a';
  11. while(t.size() && t.back() <= c) {
  12. res += t.back();
  13. t.pop_back();
  14. }
  15. while(k <= pos[i]){
  16. if(s[k] == c) res += c;
  17. else t += s[k];
  18. k ++;
  19. }
  20. }
  21. reverse(t.begin(), t.end());
  22. return res + t;
  23. }
  24. };

二、AcWing周赛 72

1、4624.最小值

(1)原题链接:4624. 最小值 - AcWing题库

(2)解题思路:

        小学数学题,思路见代码。

(3)参考代码:

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstring>
  4. using namespace std;
  5. int main()
  6. {
  7. int t;
  8. cin >> t;
  9. while(t --) {
  10. int a, b;
  11. cin >> a >> b;
  12. int c = (a + b) / 3;
  13. int res = min(min(a, b), c);
  14. cout << res << endl;
  15. }
  16. return 0;
  17. }

 

2、4625.压缩文件

(1)原题链接:4625. 压缩文件 - AcWing题库

(2)解题思路:

        1、先保存文件未被压缩时的所占空间大小总和。

        2、用一个数组维护文件压缩前后的大小的差值,并排序。

        3、从大到小依次减去差值,直到所占空间小于等于优盘的空间,减去的差值个数就是我们需要压缩的最少的文件数量。

(注意用long long保存当前文件所占空间,题目数据过大容易爆int)

(3)参考代码:

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstring>
  4. #include <vector>
  5. using namespace std;
  6. typedef long long LL;
  7. int main()
  8. {
  9. int n, m;
  10. cin >> n >> m;
  11. vector<int> tmp;
  12. LL sum = 0;
  13. for(int i = 0; i < n; i ++ ) {
  14. int a, b;
  15. cin >> a >> b;
  16. sum += a;
  17. tmp.push_back((a - b));
  18. }
  19. sort(tmp.rbegin(), tmp.rend());
  20. if(sum <= m) {
  21. cout << "0";
  22. return 0;
  23. }
  24. else {
  25. int res = 0;
  26. for(int i = 0; i < n; i ++ ) {
  27. sum -= tmp[i];
  28. res ++;
  29. if(sum <= m) {
  30. cout << res;
  31. return 0;
  32. }
  33. }
  34. }
  35. cout << "-1";
  36. return 0;
  37. }

3、4626.最小移动距离

(1)原题链接:4626. 最小移动距离 - AcWing题库

(2)解题思路:

        1、本题的本质是一个基环树。

        2、存不存在答案只需要判断是否每个点的入度都是 1,若存在不为 1 的点, 那么就不存在答案。

        3、利用并查集,求出每个连通块的节点个数的最小公倍数即为答案。

(3)参考代码:

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstring>
  4. using namespace std;
  5. const int N = 110;
  6. int n;
  7. //d存入度,p存并查集,s存每个并查集大小
  8. int d[N], p[N], s[N];
  9. int find(int x)
  10. {
  11. if(p[x] != x) p[x] = find(p[x]);
  12. return p[x];
  13. }
  14. int gcd(int a, int b)
  15. {
  16. return b ? gcd(b, a % b) : a;
  17. }
  18. int work()
  19. {
  20. for(int i = 1; i <= n; i ++ ) {
  21. if(d[i] != 1) return -1;
  22. }
  23. int res = 1;
  24. for(int i = 1; i <= n; i ++ ) {
  25. if(i == p[i]){
  26. int len = s[i];
  27. if(len % 2 == 0) len /= 2;
  28. res = res * (len / gcd(res, len));
  29. }
  30. }
  31. return res;
  32. }
  33. int main()
  34. {
  35. cin >> n;
  36. //初始化并查集
  37. for(int i = 1; i <= n; i ++ ) p[i] = i, s[i] = 1;
  38. for(int i = 1; i <= n; i ++ ) {
  39. int x;
  40. cin >> x;
  41. d[x] ++;
  42. int a = find(i), b = find(x);
  43. //若两个点不在一个连通块中,则合并这两个点
  44. if(a != b) {
  45. s[b] += s[a];
  46. p[a] = b;
  47. }
  48. }
  49. cout << work() << endl;
  50. return 0;
  51. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号