LeetCode63双周赛
https://leetcode-cn.com/contest/biweekly-contest-63/
- 使每位学生都有座位的最少移动次数
// 贪心
class Solution {
public:
int minMovesToSeat(vector<int>& seat, vector<int>& stu) {
sort(seat.begin(), seat.end());
sort(stu.begin(), stu.end());
int ans = 0;
for (int i = 0; i < seat.size(); i++) {
ans += abs(seat[i] - stu[i]);
}
return ans;
}
};
- 如果相邻两个颜色均相同则删除当前颜色
// 遍历统计
class Solution {
public:
bool winnerOfGame(string c) {
int n = c.length();
int a = 0, b = 0;
for (int i = 1; i < n - 1; i++) {
if (c[i] == 'A' && c[i - 1] == 'A' && c[i + 1] == 'A') {
a++;
}
if (c[i] == 'B' && c[i - 1] == 'B' && c[i + 1] == 'B') {
b++;
}
}
if (a <= b) {
return false;
} else {
return true;
}
}
};
- 网络空闲的时刻
// 单源点最短路,后求时间
const int maxn = 1e6;
struct Edge {
int from, to, dist;
Edge(int f, int t, int d): from(f), to(t), dist(d) {}
};
struct HeapNode {
int d, u;
bool operator<(const HeapNode& rhs) const {
return d > rhs.d;
}
};
struct Dijkstra {
int n, m;
vector<Edge> edges;
vector<int> G[maxn];
bool done[maxn];
int d[maxn];
int p[maxn];
void init(int x) {
n = x;
for (int i = 0; i < n; i++) G[i].clear();
edges.clear();
}
void AddEdge(int from, int to, int dist) {
edges.emplace_back(from, to, dist);
m = edges.size();
G[from].push_back(m - 1);
}
void dijkstra(int s) {
priority_queue<HeapNode> Q;
for (int i = 0; i < n; i++) d[i] = INT_MAX;
d[s] = 0;
memset(done, 0, sizeof done);
Q.push(HeapNode{0, s});
while (!Q.empty()) {
auto x = Q.top(); Q.pop();
int u = x.u;
if (done[u]) continue;
done[u] = true;
for (int i = 0; i < G[u].size(); i++) {
Edge& e = edges[G[u][i]];
if (d[e.to] > d[u] + e.dist) {
d[e.to] = d[u] + e.dist;
p[e.to] = G[u][i];
Q.push(HeapNode{d[e.to], e.to});
}
}
}
}
};
class Solution {
public:
int networkBecomesIdle(vector<vector<int>>& edges, vector<int>& p) {
Dijkstra dd;
int n = p.size();
dd.init(n);
for (auto& e: edges) {
dd.AddEdge(e[0], e[1], 1);
dd.AddEdge(e[1], e[0], 1);
}
dd.dijkstra(0);
int ans = 0;
for (int i = 1; i < p.size(); i++) {
//cout << dd.d[i] << endl;
int tmp = dd.d[i] * 2;
// 发送到接收经过tmp秒,从第一秒开始重新发送,(tmp - 1)秒发送了(tmp - 1) / p[i]条信息,故发送的总时间为(tmp - 1) / p[i] * p[i] + tmp
ans = max(ans, (tmp - 1) / p[i] * p[i] + tmp);
}
// 下一秒网络清净
return ans + 1;
}
};
- 两个有序数组的第 K 小乘积
// 参考评论区做法
// 按正负分为a1,a2,b1,b2
class Solution {
public:
using ll = long long;
// <= t 的个数
ll f(vector<int> x, vector<int> y, ll t) {
ll ret = 0, n = x.size(), m = y.size();
for (int i = 0, j = m - 1; i < n; i++) {
while (j >= 0 && (ll)x[i] * y[j] > t) j--;
ret += (j + 1);
}
return ret;
}
long long kthSmallestProduct(vector<int>& nums1, vector<int>& nums2, long long k) {
vector<int> a1, a2, b1, b2;
for (int i = 0; i < nums1.size(); i++) {
if (nums1[i] < 0) {
a1.push_back(-nums1[i]);
}
if (nums1[i] > 0) {
a2.push_back(nums1[i]);
}
}
for (int i = 0; i < nums2.size(); i++) {
if (nums2[i] < 0) {
b1.push_back(-nums2[i]);
}
if (nums2[i] > 0) {
b2.push_back(nums2[i]);
}
}
reverse(a1.begin(), a1.end()), reverse(b1.begin(), b1.end());
ll n = nums1.size(), m = nums2.size();
ll alen1 = a1.size(), alen2 = a2.size();
ll blen1 = b1.size(), blen2 = b2.size();
if (k <= alen1 * blen2 + blen1 * alen2) {
ll l = 0, r = 1e10;
// 小于0计算倒数
k = alen1 * blen2 + alen2 * blen1 - k + 1;
while (l < r) {
ll mid = l + r >> 1;
ll f1 = f(a1, b2, mid) + f(a2, b1, mid);
if (f1 >= k) r = mid;
else l = mid + 1;
}
return -l;
} else if (k > n * m - alen1 * blen1 - alen2 * blen2) {
ll l = 0, r = 1e10;
// 减去<= 0的数
k -= (n * m - alen1 * blen1 - alen2 * blen2);
while (l < r) {
ll mid = l + r >> 1;
ll f1 = f(a1, b1, mid) + f(b2, a2, mid);
if (f1 >= k) r = mid;
else l = mid + 1;
}
return l;
}
return 0;
}
};