第107场双周赛补题
6892. 最大字符串配对数目 - 力扣(LeetCode)
思路:暴力模拟
class Solution { public: bool check(string a, string b) { for(int i = 0; i < 2; i ++ ) if(a[i] != b[1 - i]) return false; return true; } int maximumNumberOfStringPairs(vector<string>& words) { int res = 0; for(int i = 0; i < words.size(); i ++ ) for(int j = i + 1; j < words.size(); j ++ ) if(check(words[i], words[j])) res ++ ; return res; } };
6895. 构造最长的新字符串 - 力扣(LeetCode)
思路:贪心,找规律推公式
class Solution { public: int longestString(int x, int y, int z) { if(x == y) return min(x, y) * 4 + z * 2; else return min(x, y) * 4 + z * 2 + 2; } };
6898. 字符串连接删减字母 - 力扣(LeetCode)
思路:dp,f[i, j, k]三维分别表示前i个字符串,首字母以及尾字母,意义是长度的最小值
class Solution { public: const int INF = 0x3f3f3f3f; int minimizeConcatenatedLength(vector<string>& words) { int n = words.size(); int f[n][26][26]; memset(f, 0x3f, sizeof f); f[0][words[0][0] - 'a'][words[0].back() - 'a'] = words[0].size(); for(int i = 1; i < n; i ++ ) { int sz = words[i].size(), x = words[i][0] - 'a', y = words[i].back() - 'a'; for(int j = 0; j < 26; j ++ )//枚举已连接的字符串的开头 for(int k = 0; k < 26; k ++ )//枚举末尾 { //将当前字符串接在前面 if(y == j) f[i][x][k] = min(f[i][x][k], f[i - 1][j][k] + sz - 1); else f[i][x][k] = min(f[i][x][k], f[i - 1][j][k] + sz); //将当前字符串接在后面 if(x == k) f[i][j][y] = min(f[i][j][y], f[i - 1][j][k] + sz - 1); else f[i][j][y] = min(f[i][j][y], f[i - 1][j][k] + sz); } } int res = INF; for(int i = 0; i < 26; i ++ ) for(int j = 0; j < 26; j ++ ) res = min(res, f[n - 1][i][j]); return res; } };
6468. 统计没有收到请求的服务器数目 - 力扣(LeetCode)
思路:排序后用哈希+双指针,维护当前收到了信息的服务器的数量
class Solution { public: typedef pair<int, int> PII; vector<int> countServers(int n, vector<vector<int>>& logs, int x, vector<int>& queries) { sort(logs.begin(), logs.end(), [](vector<int> &a, vector<int> &b) { return a[1] < b[1]; }); int nq = queries.size(); vector<PII> vec; for(int i = 0; i < nq; i ++ ) vec.push_back({queries[i], i}); sort(vec.begin(), vec.end()); vector<int> res(nq); unordered_map<int, int> mp;//mp[x] 表示服务器 x 在当前区间内收到了几条消息 int l = 0, r = 0; for(auto u : vec) { while (r < logs.size() && logs[r][1] <= u.first) mp[logs[r][0]] ++ , r ++ ; while (l < logs.size() && logs[l][1] < u.first - x) { int &t = mp[logs[l][0]]; t -- ; if(t == 0) mp.erase(logs[l][0]); l ++ ; } res[u.second] = n - (int)mp.size(); } return res; } };
第351场周赛补题
思路:枚举
class Solution { public: int getpre(int x) { while (x >= 10) x /= 10; return x; } int getsuf(int x) { return x % 10; } int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } int countBeautifulPairs(vector<int>& nums) { int res = 0; int n = nums.size(); for(int i = 0; i < n; i ++ ) { for(int j = i + 1; j < n; j ++ ) { int a = getpre(nums[i]), b = getsuf(nums[j]); if(gcd(a, b) == 1) res ++ ; } } return res; } };
2749. 得到整数零需要执行的最少操作数 - 力扣(LeetCode)
思路:枚举,将题目转化为求num1 - num2 * k 能否拆成k个2的i次方,其中__builtin_popcountll()是用来求该数字在二进制形式下1的个数的库函数
class Solution { public: int makeTheIntegerZero(int num1, int num2) { for(long long k = 1; k <= num1 - num2 * k; k ++ ) if(k >= __builtin_popcountll(num1 - num2 * k)) return k; return -1; } };
2750. 将数组划分成若干好子数组的方式 - 力扣(LeetCode)
思路:划分的方式其实只能在两个1中间选择,我们将每两个1之间的距离求出来就可以得出可以划分的空,然后乘法原理累乘起来就是答案
class Solution { public: typedef long long LL; LL mod = 1e9 + 7; int numberOfGoodSubarraySplits(vector<int>& nums) { LL n = nums.size(); LL res = 0; LL pre = -1; LL count = 0; for(LL i = 0; i < n; i ++ ) if(nums[i] == 1) { count ++ ; if(count == 1) pre = i; else { if(count == 2) res = (i - pre) % mod; else res = res % mod * (i - pre) % mod; pre = i; } } if(count == 1) return 1; else return res % mod; } };
思路:桟的运用,和行星碰撞差不多
class Solution { public: vector<int> survivedRobotsHealths(vector<int>& positions, vector<int>& healths, string directions) { stack<int> st; int n = positions.size(), id[n]; iota(id, id + n, 0); sort(id, id + n, [&](const int i, const int j) { return positions[i] < positions[j]; }); for(int i : id) { if(directions[i] == 'R') { st.push(i); continue; } while (!st.empty()) { int top = st.top(); if(healths[top] > healths[i]) { healths[top] -- ; healths[i] = 0; break; } if(healths[top] == healths[i]) { healths[top] = 0; healths[i] = 0; st.pop(); break; } if(healths[top] < healths[i]) { healths[top] = 0; st.pop(); healths[i] -- ; } } } healths.erase(remove(healths.begin(), healths.end(), 0), healths.end()); return healths; } };