赞
踩
(1)原题链接:力扣https://leetcode.cn/problems/the-employee-that-worked-on-the-longest-task/
(2)解题思路:
1、用pair数组保存每个id以及对应的任务的完成时间。
2、按完成时间所花费的大小顺序排序。
3、遍历数组,找到时间的最大值,若存在相同值,返回id较小的即可。
(3)参考代码:
- class Solution {
- public:
- int hardestWorker(int n, vector<vector<int>>& logs) {
- vector<pair<int, int>> a;
-
- a.push_back({logs[0][1], logs[0][0]});
-
- for(int i = 1; i < logs.size(); i ++ ) {
- int t = logs[i][1] - logs[i - 1][1];
- a.push_back({t, logs[i][0]});
- }
-
- sort(a.begin(), a.end());
-
- int res = 0;
- for(int i = a.size() - 1; i > 0; i --) {
- if(a[i].first > a[i - 1].first) {
- res = a[i].second;
- break;
- }
-
- if(a[i].first == a[i - 1].first) {
- res = min(a[i].second, a[i - 1].second);
- }
- }
-
- return res;
- }
- };
(1)原题链接:力扣https://leetcode.cn/problems/find-the-original-array-of-prefix-xor/
(2)解题思路:
这题就是前缀和的逆运算。具体思路如下:
(3)参考代码:
- class Solution {
- public:
- vector<int> findArray(vector<int>& pref) {
- int n = pref.size();
- vector<int> res(n);
- res[0] = pref[0];
- for (int i = 1; i < n; i ++ )
- res[i] = pref[i] ^ pref[i - 1];
- return res;
- }
- };
(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)参考代码:
- class Solution {
- public:
- string robotWithString(string s) {
- string res, t;
- //保存每个字母最后出现的位置
- vector<int> pos(26, -1);
-
- for(int i = 0; i < s.size(); i ++ )
- pos[s[i] - 'a'] = i;
-
- for(int i = 0, k = 0; i < 26 && k < s.size(); i ++ ) {
- char c = i + 'a';
- while(t.size() && t.back() <= c) {
- res += t.back();
- t.pop_back();
- }
-
- while(k <= pos[i]){
- if(s[k] == c) res += c;
- else t += s[k];
- k ++;
- }
- }
-
- reverse(t.begin(), t.end());
- return res + t;
- }
- };
二、AcWing周赛 72
(1)原题链接:4624. 最小值 - AcWing题库
(2)解题思路:
小学数学题,思路见代码。
(3)参考代码:
- #include <iostream>
- #include <algorithm>
- #include <cstring>
-
- using namespace std;
-
- int main()
- {
- int t;
- cin >> t;
-
-
- while(t --) {
- int a, b;
- cin >> a >> b;
-
- int c = (a + b) / 3;
-
- int res = min(min(a, b), c);
- cout << res << endl;
- }
- return 0;
- }
(1)原题链接:4625. 压缩文件 - AcWing题库
(2)解题思路:
1、先保存文件未被压缩时的所占空间大小总和。
2、用一个数组维护文件压缩前后的大小的差值,并排序。
3、从大到小依次减去差值,直到所占空间小于等于优盘的空间,减去的差值个数就是我们需要压缩的最少的文件数量。
(注意用long long保存当前文件所占空间,题目数据过大容易爆int)
(3)参考代码:
- #include <iostream>
- #include <algorithm>
- #include <cstring>
- #include <vector>
-
- using namespace std;
-
- typedef long long LL;
-
- int main()
- {
- int n, m;
- cin >> n >> m;
-
- vector<int> tmp;
- LL sum = 0;
- for(int i = 0; i < n; i ++ ) {
- int a, b;
- cin >> a >> b;
- sum += a;
- tmp.push_back((a - b));
- }
-
- sort(tmp.rbegin(), tmp.rend());
-
- if(sum <= m) {
- cout << "0";
- return 0;
- }
- else {
- int res = 0;
- for(int i = 0; i < n; i ++ ) {
- sum -= tmp[i];
- res ++;
- if(sum <= m) {
- cout << res;
- return 0;
- }
- }
- }
-
- cout << "-1";
- return 0;
- }
(1)原题链接:4626. 最小移动距离 - AcWing题库
(2)解题思路:
1、本题的本质是一个基环树。
2、存不存在答案只需要判断是否每个点的入度都是 1,若存在不为 1 的点, 那么就不存在答案。
3、利用并查集,求出每个连通块的节点个数的最小公倍数即为答案。
(3)参考代码:
- #include <iostream>
- #include <algorithm>
- #include <cstring>
-
- using namespace std;
-
- const int N = 110;
-
- int n;
- //d存入度,p存并查集,s存每个并查集大小
- int d[N], p[N], s[N];
-
- int find(int x)
- {
- if(p[x] != x) p[x] = find(p[x]);
- return p[x];
- }
-
- int gcd(int a, int b)
- {
- return b ? gcd(b, a % b) : a;
- }
-
- int work()
- {
- for(int i = 1; i <= n; i ++ ) {
- if(d[i] != 1) return -1;
- }
-
- int res = 1;
- for(int i = 1; i <= n; i ++ ) {
- if(i == p[i]){
- int len = s[i];
- if(len % 2 == 0) len /= 2;
- res = res * (len / gcd(res, len));
- }
- }
- return res;
- }
-
- int main()
- {
- cin >> n;
- //初始化并查集
- for(int i = 1; i <= n; i ++ ) p[i] = i, s[i] = 1;
-
- for(int i = 1; i <= n; i ++ ) {
- int x;
- cin >> x;
- d[x] ++;
- int a = find(i), b = find(x);
- //若两个点不在一个连通块中,则合并这两个点
- if(a != b) {
- s[b] += s[a];
- p[a] = b;
- }
- }
-
- cout << work() << endl;
-
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。