AcWing第1场周赛题解
A. AcWing 3577. 选择数字
题目链接:https://www.acwing.com/problem/content/3580/
题目大意:从两个数组种各选出一个数,使它们的和不包含在两个数列中。
解题思路:因为元素都是正整数,所以找最大值即可。
示例程序:
#include <bits/stdc++.h>
using namespace std;
int mx() {
int n, a, res = 0;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a;
res = max(res, a);
}
return res;
}
int n, m, a[101], b[101];
int main() {
cout << mx() << " " << mx() << endl;
return 0;
}
B. AcWing 3578. 最大中位数
题目链接:https://www.acwing.com/problem/content/3581/
题目大意:进行k次+1操作使中位数最大。
解题思路:贪心,不用管较小的 $\lfloor \frac{n}{2} \rfloor $ 个数,每次从较大的 \(\lceil \frac{n}{2} \rceil\) 个数中选择一个最小的执行 \(+1\) 操作。但是单独加不好,可以模拟或者二分答案。
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
int n, k, a[maxn];
bool check(int m) {
int c = k;
for (int i = n/2; i < n; i++) {
if (a[i] < m) {
c -= m - a[i];
if (c < 0)
return false;
}
else return true;
}
return true;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n >> k;
for (int i = 0; i < n; i++) cin >> a[i];
sort(a, a+n);
int l = a[n/2], r = a[n/2] + k, res;
while (l <= r) {
int mid = l + (r - l) / 2;
if (check(mid)) {
res = mid;
l = mid + 1;
} else r = mid - 1;
}
cout << res << endl;
return 0;
}
C. AcWing 3579. 数字移动
题目链接:https://www.acwing.com/problem/content/3582/
题目大意:找每个数多少次能变回自己。
解题思路:找环, \(i \rightarrow p_i\) 一条边,判断每个点所在的有向环长度。搜索。
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
int T, n, p[maxn], bl[maxn], dis[maxn]; // bl[i]表示搜索起点编号,dis[s]表示s所在环长度
void dfs(int u, int s, int d) { // u当前节点,s搜索起点
bl[u] = s;
if (p[u] == s) {
dis[s] = d;
return;
}
dfs(p[u], s, d+1);
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> T;
while (T--) {
cin >> n;
for (int i = 1; i <= n; i++) cin >> p[i];
memset(bl, 0, sizeof(int)*(n+1));
for (int i = 1; i <= n; i++)
if (!bl[i])
dfs(i, i, 1);
for (int i = 1; i <= n; i++) {
if (i > 1) cout << " ";
cout << dis[bl[i]];
}
cout << endl;
}
return 0;
}
补充:今天出数据发现 dfs 解法可能会爆栈(dfs深度过高),所以更新一种 bfs 解法,如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
int T, n, p[maxn], bl[maxn], dis[maxn]; // bl[i]表示搜索起点编号,dis[s]表示s所在环长度
void bfs(int s) { // u当前节点,s搜索起点
for (int u = s, d = 1; ; u = p[u], d++) {
bl[u] = s;
if (p[u] == s) {
dis[s] = d;
break;
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> T;
while (T--) {
cin >> n;
for (int i = 1; i <= n; i++) cin >> p[i];
memset(bl, 0, sizeof(int)*(n+1));
for (int i = 1; i <= n; i++)
if (!bl[i])
bfs(i);
for (int i = 1; i <= n; i++) {
if (i > 1) cout << " ";
cout << dis[bl[i]];
}
cout << endl;
}
return 0;
}