Codeforces Round 1050 (Div. 4) 题解
A
图灵测试题,做不出来的可以被判定为机器人了。
直接判断 \(n\) 的奇偶分情况做即可。
#include <bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
int n, x;
void solve () {
cin >> x >> n;
if (n&1) { cout << x << "\n"; return; }
else cout << 0 << "\n";
}
int main () {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int _ = 1; cin >> _;
while (_--) solve();
return 0;
}
B
有点小唬人啊这题,不过照样是图灵测试题。
不难发现无论怎么走,无论斜着走还是一个直角走也好,最优的情况都是把所有的 Laser 都经过一遍。
#include <bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
const int N = 2e5+100;
int n, m, x, y;
int a[N], b[N];
void solve () {
cin >> n >> m >> x >> y;
for (int i = 1;i <= n;i++) cin >> a[i];
for (int i = 1;i <= m;i++) cin >> b[i];
cout << n+m << "\n";
}
int main () {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int _ = 1; cin >> _;
while (_--) solve();
return 0;
}
C
em,有点小恶心,不过大体是分类讨论。想到如果剩余奇数时间我们可以直接到达另一边,如果是偶数时间我们可以直接到达原来的边。
于是可以想到当目标边和我们原边一样的时候,考虑能得到的最大的偶数时间,不同时则考虑能得到的最大的奇数时间。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pii pair <int, int>
const int N = 2e5+100;
ll n, m;
pii op[N];
void solve () {
cin >> n >> m;
for (int i = 1;i <= n;i++) cin >> op[i].first >> op[i].second;
ll now = 0, side = 0, ans = 0;
for (int i = 1;i <= n;i++) {
if (op[i].first > m) break;
ll minu = op[i].first - now;
if (side == op[i].second) {
if (minu&1) ans += (minu-1);
else ans += minu;
} else {
if (minu&1) ans += minu;
else ans += (minu-1);
}
now = op[i].first, side = op[i].second;
}
if (now < m) ans += (m - now);
cout << ans << "\n";
}
int main () {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int _ = 1; cin >> _;
while (_--) solve();
return 0;
}
D
小小思维题,通过题意不难发现,如果没有奇数那么无法得到任何除了 \(0\) 以外的答案。
此时考虑有奇数的情况,不难发现因为经过奇数就会改变状态,于是考虑一开始去添加偶数的时候经过的奇数是最大的,然后关闭时经过的偶数是最小的,然后以此类推,让大的对应小的即可。
#include <bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
const int N = 2e5+100;
int n, a[N];
bool cmp (int x, int y) {
return x > y;
}
void solve () {
cin >> n;
int cnt = 0;
for (int i = 1;i <= n;i++) {
cin >> a[i];
if (a[i] & 1) cnt++;
}
if (!cnt) { cout << "0\n"; return; }
ll ans = 0;
for (int i = 1;i <= n;i++)
if (!(a[i]&1)) ans += a[i], a[i] = 0;
sort(a+1, a+n+1, cmp);
deque <int> q;
for (int i = 1;i <= n;i++)
if (a[i]) q.push_back(a[i]);
if (q.size() == 1) ans += q.back();
else {
while (!q.empty() && q.size() > 1) {
ans += q.front();
q.pop_front();
q.pop_back();
}
if (q.size() == 1) ans += q.back();
}
cout << ans << "\n";
}
int main () {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int _ = 1; cin >> _;
while (_--) solve();
return 0;
}
E
滑动窗口的偏模板题,不难发现每一个数字都有其出现的次数限制,只需要在窗口滑动的过程中记录一下每一个数字的出现次数即可,如果有不符合要求的数字就右移左端点急么,答案就是左右端点中的 \([l, l], [l, l+1], \dots, [l, r]\),这样子计算可以避免重复和漏算。
#include <bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
const int N = 2e5+100;
int n, k, a[N], cnt[N], de[N];
void solve () {
cin >> n >> k;
memset(cnt, 0, sizeof(cnt));
memset(de, 0, sizeof(de));
// cout << "[+] " << n << '-' << k << "\n";
for (int i = 1;i <= n;i++) {
cin >> a[i];
cnt[a[i]]++;
}
for (int i = 1;i <= n;i++)
if (cnt[i]) {
if (cnt[i]%k) { cout << "0\n"; return; }
de[i] = cnt[i] / k;
}
// for (int i = 1;i <= n;i++) cout << de[i] << " ";
// cout << "\n";
memset(cnt, 0, sizeof(cnt));
ll ans = 0;
int l = 1, r = 1;
while (l <= r && r <= n) {
cnt[a[r]]++;
while (cnt[a[r]] > de[a[r]]) cnt[a[l]]--, l++;
ans += (r-l+1);
r++;
}
cout << ans << "\n";
}
int main () {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int _ = 1; cin >> _;
while (_--) solve();
return 0;
}
F
stl 魅力时刻。
直接用 vector 来存输入,然后模拟排序,每次我就选我要的目标位置的最小字典序。
举个例子:第一次我要选择第一个位置上的字母,此时整个 ans 的字符串都是空的,所以我们考虑直接把字典序最小的塞进去。假设我们塞得字符串的长度为 \(len\),那么我们要考虑的索引就变为了 \(len\)(假设下标从 \(0\) 开始),然后将剩余的数字串都只保留 \(len\) 这个索引之后的(包括这个索引),以此类推。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
int n;
void solve () {
cin >> n;
vector <vector <int> > a(n);
int maxn = 0, pos = 0;
for (int i = 0;i < n;i++) {
int k; cin >> k;
for (int j = 0;j < k;j++) {
int x; cin >> x;
a[i].push_back(x);
}
maxn = max(maxn, k);
}
vector <int> ans(maxn);
while (pos < maxn) {
sort(a.begin(), a.end());
for (int i = 0;i < a[0].size();i++) ans[pos++] = a[0][i];
vector <vector <int> > b;
int now = a[0].size();
for (int i = 1;i < a.size();i++) {
vector <int> c;
for (int j = now;j < a[i].size();j++) c.push_back(a[i][j]);
if (c.size()) b.push_back(c);
}
a = b;
}
for (auto tmp : ans) cout << tmp << " ";
cout << "\n";
}
int main () {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int _ = 1; cin >> _;
while (_--) solve();
return 0;
}
浙公网安备 33010602011771号