A题:green_gold_dog, array and permutation
题目大意:
给你一个大小为 n 的数组 a, 让你构造一个数组 b (b中的元素是的排列), 对于
,使得出现的
种类最多。
思路:
贪心。题目要求种类最多,那最多一定是 n 个。
我们固定 b 为 , 发现如果 a 数组是降序的话,它们的差值
一定是单调递减的,这
样就使得种类一定为 n 个, 所以我们可以sort一遍 a, 然后按位置放 b。
// Problem: A. green_gold_dog, array and permutation
// Contest: Codeforces - Codeforces Round 897 (Div. 2)
// URL: https://codeforces.com/contest/1867/problem/A
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
typedef pair<int, int> PII;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int tt; cin >> tt;
while (tt -- ) {
int n; cin >> n;
vector<PII> a(n);
for (int i = 0; i < n; i ++ ) {
int x; cin >> x;
a[i] = {x, i};
}
sort(a.begin(), a.end(), [](PII aa, PII bb) {
return aa.first > bb.first;
});
vector<int> res(n);
for (int i = 0; i < n; i ++ ) {
res[a[i].second] = i + 1;
}
for (auto x : res) cout << x << ' ';
cout << endl;
}
return 0;
}
B题: XOR Palindromes
题目大意:
给你一个由01组成大小为 n 字符串 s,要求你输出一个大小为 n + 1的字符串,第 i 的位置上代表
着进行了 i 次异或操作(每位至多操作一次), 如果可以使得 s 变成回文串,那么该位上是1,
否则是0。 最后将你构造出的字符串输出。
思路:
我们先统计一下,一开始到底至少需要多少次才能使得 s 变成回文串,记这个次数为 cnt
在操作次数小于 cnt 的情况下, 一定是 0,无法将其变成回文串。
然后我们进行遍历, 将过程中的部分,可以操作两次使得其还是个回文串。
但是我们值得注意的是, n 为奇数的情况下, 还可以多操作一次中间。
// Problem: B. XOR Palindromes
// Contest: Codeforces - Codeforces Round 897 (Div. 2)
// URL: https://codeforces.com/contest/1867/problem/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
typedef pair<int, int> PII;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int tt; cin >> tt;
while (tt -- ) {
int n; cin >> n;
string s; cin >> s;
s = " " + s;
int cnt = 0;
for (int i = 1; i <= n / 2; i ++ ) {
if (s[i] != s[n - i + 1])
cnt += 1;
}
vector<int> res(n + 2);
res[cnt] = 1;
if (n & 1) res[cnt + 1] = 1;
for (int i = 1; i <= n / 2; i ++ ) {
if (s[i] == s[n - i + 1]) {
cnt += 2;
res[cnt] = res[cnt + n % 2] = 1;
}
}
for (int i = 0; i <= n; i ++ ) cout << res[i];
cout << endl;
}
return 0;
}
C题: Salyg1n and the MEX Game
题目大意:
给定一个集合 S, 你为先手,每次可以往集合里加入一个数 x, 另一个人会每次删除一个数 y,
y小于x。定义你的得分为最后的Mex,请给出一个方案,使得这个方案得分大于等于两者都以
最优方式下棋的结果。
游戏以另一个人无法删除或者由你来结束(你是最后一步棋)
思路:
这个比 B 题简单多了啊,如果一开始你的得分是 3,集合为{0, 1, 2},那么你一开始可以往集合
里放入 3,使得你的得分变成了 4。后续你只需模仿另一个人的操作,他删什么,你就加什么。
这样就是两者都以最优方式下棋的结果。
证:一开始如果想让得分变大,你一定是往里面加入Mex。这样你的得分就会变成 >= Mex + 1
另一个人删数只能删 <= Mex 的,记作 y,这样你的得分就会变成 y,为了保持你的最大得分
你不得不跟他进行同样的操作。
// Problem: C. Salyg1n and the MEX Game
// Contest: Codeforces - Codeforces Round 897 (Div. 2)
// URL: https://codeforces.com/contest/1867/problem/C
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
typedef pair<int, int> PII;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int tt; cin >> tt;
while (tt -- ) {
int n; cin >> n;
unordered_set<int> s;
for (int i = 0; i < n; i ++ ) {
int x; cin >> x;
s.insert(x);
}
int i = 0;
while (s.count(i)) i += 1;
int y = 0;
while (y >= 0) {
cout << i << endl;
cin >> y;
i = y;
if (y <= -1) break;
}
}
return 0;
}
D题:Cyclic Operations
放个代码,之后补思路qwq
跟后续补题一起传。
// Problem: D. Cyclic Operations
// Contest: Codeforces - Codeforces Round 897 (Div. 2)
// URL: https://codeforces.com/contest/1867/problem/D
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
#include <bits/stdc++.h>
#define endl '\n'
#define Yes cout << "YES" << endl
#define No cout << "NO" << endl
using namespace std;
using ll = long long;
typedef pair<int, int> PII;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int tt; cin >> tt;
while (tt -- ) {
int n, k; cin >> n >> k;
vector<int> a(n + 1);
for (int i = 1; i <= n; i ++ ) cin >> a[i];
if (k == 1) {
bool ok = true;
for (int i = 1; i <= n; i ++ ) {
if (a[i] != i) {
ok = false;
}
}
if (ok) Yes;
else No;
}else {
bool ok = true;
vector<int> vis(n + 1, false);
for (int i = 1; i <= n; i ++ ) {
if (vis[i]) continue;
unordered_set<int> s;
int now = i;
while (!vis[now]) {
s.insert(now);
vis[now] = true;
now = a[now];
}
if (s.count(now)) {
int sz = 1;
for (int j = a[now]; j != now; j = a[j], sz += 1);
if (sz != k) {
ok = false;
}
}
}
if (ok) Yes;
else No;
}
}
return 0;
}