Codeforces Global Round 13 A-D题题解
写在前边
A. K-th Largest Value
链接:A题链接
题目大意:
有一个字串只由组成,有两个操作,是让其中变为,是询问数组中第大的数。
思路:
很简单了,字串中元素只在中变化,要问第大的数字,那么非即,就用一个维护的数量就好了
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <cstring>
//#pragma GCC optimize(2)
//#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
#define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long>
#define endl '\n'
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI;
const int Mod = 10000007;
const int N = 1E5 + 10;
int a[N];
void solve() {
int n, q;
scanf("%d%d", &n, &q);
map<int, int> cnt;
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
cnt[a[i]]++;
}
while (q--) {
int t, x;
scanf("%d%d", &t, &x);
if (t == 1) {
if (a[x] == 1) {
a[x] = 0;
cnt[0]++, cnt[1]--;
} else {
a[x] = 1;
cnt[1]++, cnt[0]--;
}
} else if (t == 2) {
if (cnt[1] >= x) puts("1");
else puts("0");
}
}
}
int main()
{
//ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
solve();
return 0;
}
B. Minimal Cost
链接:B题链接
题目大意:
每行一个箱子,第行箱子的坐标为,你的任务就是推箱子,然后把利用最小的花费把开一条路使得你可以从左上角走到右下角。
思路:
注意
- 每行就一个!
- 你可以随便方向的走!
那么这样就很简单了,只需要在一列箱子中开一个口就好了,然后不断更新答案即可。
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <cstring>
//#pragma GCC optimize(2)
//#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
#define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long>
#define endl '\n'
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI;
const int Mod = 10000007;
const int N = 110;
int a[N];
void solve() {
int n, u, v;
scanf("%d%d%d", &n, &u, &v);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
int res = 2e9 + 10;
for (int i = 2; i <= n; i++) {
if (abs(a[i] - a[i - 1]) > 1) res = 0;
if (a[i] == a[i - 1]) res = min(res, v + min(v, u));
if (abs(a[i] - a[i - 1]) == 1) res = min(res, min(v, u));
}
printf("%d\n", res);
}
int main()
{
//ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int t;
scanf("%d", &t);
while (t--) {
solve();
}
return 0;
}
C. Pekora and Trampoline
链接:C题链接
题目大意:
跳床,有个跳床,床的高度为,每在上边跳一次那么减小,每次跨越着跳,当前在那么一步会跳到去,每次可以从任意一个跳床开始跳,直到跳出所有跳床算一次操作,那么经过多少次操作,所有的都变为,注意已经变为的床不会再减小。
思路:
贪心的想,假如我们要是所有的床都变为,那么我们每次一定得从最左边跳到最右边,所以不如直接贪心加模拟的方法解题。
1.维护一个数组,表示已经在第张床上跳了次。
2.更新答案,即如果说明还需要在第i张床上跳次,如果,那么说明第张床上已经变为。同时如果在第i张床上跳,因为每次减一,直到减法为(就没必要跳了),那么会影响后边第床。
3. 还有就是,如果第张床上跳的过多,即已经变为了,那么第张床上多余的跳跃次数可以转移到下一张床上。
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <cstring>
//#pragma GCC optimize(2)
//#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
#define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long>
#define endl '\n'
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI;
const int Mod = 10000007;
LL gcd(LL a, LL b) {
return b ? gcd(b, a % b) : a;
}
const int N = 5010;
int s[N];
int p[N];
void solve() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &s[i]);
LL res = 0;
memset(p, 0, sizeof p);
for (int i = 1; i <= n; i++) {
int x = max(0, s[i] - p[i] - 1);
res += x;
for (int j = i + 2; j <= min(n, i + s[i]); j++) {
p[j]++;
}
p[i + 1] += max(p[i] - s[i] + 1, 0);
}
printf("%lld\n", res);
}
int main()
{
//ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int t;
scanf("%d", &t);
while (t--) {
solve();
}
return 0;
}
D. Zookeeper and The Infinite Zoo
链接:D题链接
题目大意:
可以在结点到连一条边,当前仅当的时候,然后给定个询问,每次两个端点, 问是否能从到。
思路:
首先发现两个性质:
- 假如现结点为,那么它一定可以转移到,很显然。
- 还有就是要满足,那么起码满足,否则直接掉即可
然后再推到发现,中的个数必须要大于等于中的个数,为什么呢?
我们令.
我们发现,因为,那么说明,与的二进制数中存在的位数一定在同一位啊,否则不可能按位与得到,然后实现转移到,那么相对于来说肯定是其中的某些进位才得到了,那么所以说中得个数肯定是小于等于中得个数的,举两个例子:
, ,那么。的个数减少了。
, ,那么。的个数不变。
那么单纯满足这个条件就对了吗,当然不是。
还要满足,中的每一位要高于中每一位的,总不能越转移越低吧。那么满足这两个条件,到就可以进行转移了,那么上边的操作都可以用运算就可以了
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <cstring>
//#pragma GCC optimize(2)
//#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
#define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long>
#define endl '\n'
#define pub push_back
#define pob pop_back
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI;
const int Mod = 10000007;
int lowbit(int x) {
return x & (-x);
}
void solve() {
int u, v;
scanf("%d%d", &u, &v);
if (u > v) {
puts("NO");
return;
}
int uu = u, vv = v;
int cnt1 = 0, cnt2 = 0;
while (uu) { //u中1的个数
uu -= lowbit(uu);
cnt1++;
}
while (vv) { //v中1的个数
vv -= lowbit(vv);
cnt2++;
}
while (u && v) { //必须往高位推才行
if (lowbit(u) > lowbit(v)) {
puts("NO");
return;
}
u -= lowbit(u), v -= lowbit(v);
}
if (cnt1 >= cnt2) puts("YES");
else puts("NO");
}
int main()
{
//ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int t;
scanf("%d", &t);
while (t--) {
solve();
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端