posts - 15,comments - 0,views - 884

Codeforces Round #808 (Div. 2)

传送门https://codeforces.com/contest/1708

错过了,第二天vp的,只写出了AB就卡C了,竟然看不出是贪心555

A. Difference Operations

题意:给一个数组,由如下操作,问能不能使得a2an 全为0

操作是选择一个i,使得ai=aiai1

:显然a2a1的倍数,才可能被剪成0,同理a3a2

那么意味着所有数字都得是a1的倍数,并且中间不可以被0隔断。

#include <bits/stdc++.h>
signed main() {
int t;
std::cin >> t;
while (t--) {
int n;
std::cin >> n;
int a[110] = {0};
for (int i = 1; i <= n; i++)
std::cin >> a[i];
int k = a[1];
bool f = 1;
for (int i = 2; i <= n; i++) {
if (k == 0 && a[i] != 0 || a[i] % k != 0)
f = 0;
if (a[i - 1] == 0 && a[i])
f = 0;
}
if (f)
std::cout << "YES" << std::endl;
else
std::cout << "NO" << std::endl;
}
}

B. Difference of GCDs

题意:构造一个长度为n的数组,满足所有数字都在区间[l,r]内。

并且所有gcd(i,ai) 的值互不相同。i

解法:因为gcd(i,ai)<=i 又要互不相同,那么就必须gcd(i,ai)==i 也就是说aii 然后就在[l,r]里随便找个倍数就行了。找不到就输出NO

#include <bits/stdc++.h>
#define int long long
const int N = 1e5 + 10;
int a[N];
signed main() {
std::ios::sync_with_stdio(false);
int t;
std::cin >> t;
while (t--) {
int n, l, r;
std::cin >> n >> l >> r;
bool f = 1;
for (int i = 1; i <= n; i++) {
a[i] = 0;
for (int j = (l - 1) / i * i + i; j <= r; j += i) {
if (j >= a[i]) {
a[i] = j;
break;
}
}
if (!a[i])
f = 0;
}
if (!f) {
std::cout << "NO" << std::endl;
continue;
} else {
std::cout << "YES" << std::endl;
for (int i = 1; i <= n; i++)
std::cout << a[i] << " \n"[i == n];
}
}
}

C. Doremy's IQ

题意:有n天,第i天有考试i,难度为ai 有起始智商q,当q<=0时她无法继续参加考试。

如果参加的考试ai>q那么q--。

问如何选择哪几天考试能考的次数最多。答案以01串输出。

思路:贪心地想,掉智商肯定是越迟掉越好,如果在i天选择了掉智商的考试,那么之后也要义无反顾地考下去。于是,我们可以直接二分从哪天开始掉智商并能考完后面的全部考试的。求出i最小的方案即可输出。

#include <bits/stdc++.h>
#define int long long
const int N = 1e5 + 10;
int a[N];
int ans[N];
int n, q;
std::vector<int> ve;
bool check(int p) {
int qq = q;
for (int i = 1; i < p; i++) {
if (a[i] > qq) {
ans[i] = 0;
} else {
ans[i] = 1;
}
}
for (int i = p; i <= n; i++) {
ans[i] = 1;
if (a[i] > qq)
qq--;
}
return qq >= 0;
}
signed main() {
std::ios::sync_with_stdio(false);
int t;
std::cin >> t;
while (t--) {
std::cin >> n >> q;
for (int i = 1; i <= n; i++) {
std::cin >> a[i];
}
int l = 0, r = n;
while (l < r) {
int m = (l + r) >> 1;
if (check(m)) {
r = m;
} else
l = m + 1;
}
check(l);
for (int i = 1; i <= n; i++) {
std::cout << ans[i];
}
std::cout << "\n";
}
}

D. Difference Array

题意:给一个数组。让你把它变成它的差分数组,然后升序,继续变成差分数组...

直到最终只剩一个数字,输出这个数字。

思路:直接模拟肯定不行,但是发现,随着差分操作,一定会出现大量的0,而0和0的差分还是0,那么我们就可以直接把所有的0拿出来,每次操作减一,然后算上新生成的。其他过程就暴力模拟就好了。

#include <bits/stdc++.h>
#define int long long
const int N = 1e5 + 10;
int a[N];
signed main() {
std::ios::sync_with_stdio(false);
int t;
std::cin >> t;
while (t--) {
int n;
std::cin >> n;
std::vector<int> ve[2];
for (int i = 1; i <= n; i++) {
std::cin >> a[i];
ve[0].push_back(a[i]);
}
int now = 0;
int cost0 = 0;
while (ve[now].size() >= 2) {
std::sort(ve[now].begin(), ve[now].end());
ve[now ^ 1].clear();
if (cost0) {
ve[now ^ 1].push_back(ve[now][0]);
cost0--;
}
for (int i = 0; i < ve[now].size() - 1; i++) {
int k = ve[now][i + 1] - ve[now][i];
if (k == 0) {
cost0++;
} else
ve[now ^ 1].push_back(k);
}
now ^= 1;
}
if (ve[now].size() == 0)
std::cout << 0 << "\n";
else if (ve[now].size() == 1) {
std::cout << ve[now][0] << "\n";
} else if (cost0 >= 1) {
std::sort(ve[now].begin(), ve[now].end());
int k1 = ve[now][0], k2 = ve[now][1] - ve[now][0];
std::cout << std::abs(k1 - k2) << "\n";
} else
std::cout << std::abs(ve[now][0] - ve[now][1]) << "\n";
}
}
posted on   wtn135687  阅读(40)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示