2021.10.16第63场双周赛
2037. 使每位学生都有座位的最少移动次数
思路
排序+贪心
次序相同的对应转换,最优
代码
class Solution {
public:
int minMovesToSeat(vector<int>& a, vector<int>& b) {
sort(a.begin(), a.end());
sort(b.begin(), b.end());
int ans = 0;
for (int i = 0; i < a.size(); i ++ )
ans += abs(a[i] - b[i]);
return ans;
}
};
2038. 如果相邻两个颜色均相同则删除当前颜色
思路
双指针
找到长度大于等于3的连续字符串,比较A和B的种类数量,若A多则必胜
代码
class Solution {
public:
bool winnerOfGame(string s) {
int a = 0, b = 0;
int n = s.size();
for (int i = 0; i < s.size();) {
int j = i;
while (j < s.size() && s[j] == s[i]) j ++ ;
if (j - i > 2) {
if (s[i] == 'A')
a += j - i - 2;
else
b += j - i - 2;
}
i = j;
}
return a > b;
}
};
2039. 网络空闲的时刻
思路
bfs求最短路
对于每个点来说
它所用的时间为:最后一个发出去的信息的时间 + 最短距离*2+1 的传递时间
代码
class Solution {
public:
int networkBecomesIdle(vector<vector<int>>& edges, vector<int>& p) {
int n = p.size();
vector<vector<int>> g(n, vector<int>(0));
for (auto i : edges) {
g[i[0]].push_back(i[1]);
g[i[1]].push_back(i[0]);
}
vector<int> d(n, 1e9);
d[0] = 0;
queue<int> q;
q.push(0);
while (q.size()) {
int t = q.front();
q.pop();
for (int i = 0; i < g[t].size(); i ++ ) {
int j = g[t][i];
if (d[j] == 1e9) {
d[j] = d[t] + 1;
q.push(j);
}
}
}
int ans = 0;
for (int i = 0; i < n; i ++ ) {
int res = d[i] * 2;
//若周期大于第一个信息收到回应的时间
if (p[i] < res) { //求最后一个发出信息的时间
if (res % p[i] == 0) //能整除则少一个周期
res += (res / p[i] - 1) * p[i];
else
res += (res / p[i]) * p[i];
}
//耗费时间最长的完成则空闲
ans = max(ans, res);
}
return ans + 1; //从第0秒开始
}
};
2040. 两个有序数组的第 K 小乘积
思路
二分套二分
记f(x)
为小于等于数x
的积的个数,随着x
的增大,f(x)
增大或不变,故f(x)
具有单调性,由此可以二分出x
,即最后的答案。
接下来只需求出f(x)
,两数相乘时,若一个数a
不变,则另一个数b
的变化会影响两数之积的变化,也可以通过二分找到一个最大b
,进而计算乘积小于x
的数量。计算时需对a
进行分类讨论。
代码
class Solution {
public:
long long er(long long x, vector<int>& a, vector<int>& b) { //返回小于等于x的积的个数
long long cnt = 0;
for (long long n : a) {
if (n > 0) {
if (n * b[0] > x) continue;
int l = 0, r = b.size() - 1;
while (l < r) {
int mid = l + r + 1 >> 1;
if (n * b[mid] <= x) l = mid;
else r = mid - 1;
}
cnt += l + 1;
}
else if (n < 0) {
if (n * b.back() > x) continue;
int l = 0, r = b.size() - 1;
while (l < r) {
int mid = l + r >> 1;
if (n * b[mid] <= x) r = mid;
else l = mid + 1;
}
cnt += b.size() - l;
}
else if (n == 0 && x >= 0) cnt += b.size();
}
return cnt;
}
long long kthSmallestProduct(vector<int>& nums1, vector<int>& nums2, long long k) {
long long l = -1e11, r = 1e11;
while (l < r) {
long long mid = l + r + 1 >> 1;
//如果小于mid的数的个数小于k
if (er(mid, nums1, nums2) < k) l = mid;
else r = mid - 1;
}
//返回下一个数
return l + 1;
}
};