Codeforces Round #696 (Div. 2)
Codeforces Round #696 (Div. 2)
A - Puzzle From the Future
贪心, 让长度最长, 每次试 +1,
int main() {
IOS;
for (cin >> _; _; --_) {
string s; cin >> n >> s; m = -1;
for (int i = 0; i < n; ++i) {
int c = s[i] - '0';
if (c + 1 != m) s[i] = '1', m = c + 1;
else s[i] = '0', m = c;
}
cout << s << '\n';
}
return 0;
}
B - Different Divisors
1, a, b, a * b
a, b为质数, 且 a - 1 >= d, b - a >= d即可
int prime[N], tot;
bool v[N];
void init() {
for (int i = 2; i <= 2e6; ++i) {
if (!v[i]) prime[++tot] = i;
for (int j = 1; j <= tot && prime[j] <= 2e6 / i; ++j) {
v[i * prime[j]] = 1;
if (i % prime[j] == 0) break;
}
}
}
int main() {
IOS; init();
for (cin >> _; _; --_) {
cin >> n; ll ans = *lower_bound(prime + 1, prime + tot + 1, 1 + n);
cout << (ans * (*lower_bound(prime + 1, prime + tot + 1, ans + n))) << '\n';
}
return 0;
}
C - Array Destruction
枚举哪个数和最大数一起消去就好, 在模拟判断是否满足, 听说有人是 \(O(n^3)\), 那就没啥算法了, 就是枚举模拟题意
int s[N];
bool work(multiset<int> q1, int id, vector<PII>& x) {
int a = *q1.begin(); q1.erase(q1.begin()); q1.erase(q1.find(-s[id]));
x.pb({ -a, s[id] }); bool f = 1;
for (int i = 1; i < n && f; ++i) {
int mx = *q1.begin(); q1.erase(q1.begin());
auto it = q1.find(a - mx);
if (it == q1.end()) f = 0;
else x.pb({ -mx, -*it }), q1.erase(it), a = mx;
}
if (f) return 1; vector<PII>().swap(x);
return 0;
}
int main() {
IOS;
for (cin >> _; _; --_) {
multiset<int> q1; vector<PII> y; bool f = 0;
cin >> n; rep(i, 1, n * 2) cin >> s[i], q1.insert(-s[i]); sort(s + 1, s + 1 + n * 2);
for (int i = 1; i < n * 2 && !f; ++i) f = work(q1, i, y);
if (f) {
cout << "YES\n" << y[0].fi + y[0].se << '\n';
for (auto& i : y) cout << i.fi << ' ' << i.se << '\n';
}
else cout << "NO\n";
}
return 0;
}
D - Cleaning
差分, 最左边的石子只能靠第2堆消去, 以此类推
a[1] - a[1], (a[2] - a[1]) - (a[2] - a[1]), (a[3] - a[2] + a[1]) - (a[3] - a[2] + a[1]), ... , (a[n] - a[n - 1] + a[n - 2] - ... + \((-1)^{n - 1 \& 1}\) * a[1]) - (a[n] - a[n - 1] + a[n - 2] - ... + \((-1)^{n - 1 \& 1}\) * a[1])
最终目标是所有 b[i] = a[i] - a[i- 1] + a[i - 2] - ... + \((-1)^{i - 1 xor 1}\) * a[1] >= 0 且 b[n] = 0
考虑交换 i 和 i + 1, 那么 b[1~i-1] >= 0, 且 b[i] += a[i + 1] - a[i] >= 0, 且 i + 1 ~ n, b[i + 2k + 1] -= 2 * (a[i + 1] - a[i]), b[i + 2k] += 2 * (a[i + 1] - a[i])
所以我们还要预处理 b[i], b[i + 2], ..., b[n - i & 1 ? n : n - 1] 之间的最小值
这样就是 线性 枚举交换 i 和 i + 1, 判断是否可行即可
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n; vector<ll> a(n + 1), b(n + 1), c(n + 1);
rep (i, 1, n) cin >> a[i], b[i] = a[i];
bool f = 1;
rep (i, 1, n) c[i] = b[i] -= b[i - 1], f = f & (b[i] >= 0);
f = f & b[n] == 0;
per (i, n - 2, 1) umin(c[i], c[i + 2]);
rep (i, 1, n - 1) {
if (b[i - 1] < 0 || f) break;
int t = a[i + 1] - a[i];
if (b[i] + t < 0 || c[i + 1] - 2 * t < 0 || (i + 2 <= n && c[i + 2] + 2 * t < 0)) continue;
if (b[n] + 2 * (n - i & 1 ? -t : t) == 0) f = 1;
}
cout << (f ? "YES\n" : "NO\n");
}
return 0;
}