Codeforces Round 1004 (Div. 2) 赛时记录
前言
赶紧打完补题
晚上睡觉还是盖被子吧, 太 tm 冷了
一会搜一下神秘教程, 然后就这样, 还剩下一堆题
记得问 关于最小生成树和最大流问题
注意效果剪枝, 然后就是听讲
\(\rm{A}\)
思路
样例给出的
- \(y - x = 1\)
显然可以构造 - \(y = 1\)
如果 \(x | 9\) , 显然可以构造
更一般的
- \(y - x = 1\)
显然可以构造 - 进位
本质上就是 \(9x \to 1\) , 差值如果可以构造成 \(9x - 1\) 的形式即可
代码
#include <bits/stdc++.h>
void solve() {
int a, b; scanf("%d %d", &a, &b);
if ((b - a) == 1 || (a - b) % 9 == 8) printf("Yes\n");
else printf("No\n");
}
int main()
{
int t; scanf("%d", &t);
while (t--) solve();
return 0;
}
\(\rm{B}\)
思路
题意
给定两个可重数集
你可以
- 移动 中的某个数到 中
- 如果 , 让
求最终是否可以让 中内容相同
性质
一个数 倘若出现了 次, 那么把剩下的部分全部丢给 , 一定可以处理出最后的结果
如果过程中一个数仅仅出现了 次, 或者最后那个数出现了奇数次, 那么就完蛋
代码
#include <bits/stdc++.h>
const int MAXN = 1020;
int a[MAXN];
int app[MAXN];
void solve() {
int n; scanf("%d", &n);
int mn = n + 1, mx = 0;
memset(app, 0, sizeof app);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]), app[a[i]]++, mn = std::min(mn, a[i]), mx = std::max(mx, a[i]);
for (int i = mn; i <= mx; i++) {
if (app[i] == 1 || (i == mx && (app[i] % 2) == 1)) { printf("No\n"); return; }
if (i == mx) { printf("Yes\n"); return; }
if (app[i] > 2) app[i + 1] += app[i] - 2;
}
}
int main()
{
int t; scanf("%d", &t);
while (t--) solve();
return 0;
}
总结
一类操作问题
一般是找到一种统一的操作方式, 使得能被构造的一定可以构造
一种思想是解决当前的一部分, 余下的全部转化给下一个
\(\Delta \neq 1\) 的奇偶性问题的一种传递思想就是直接把余下的部分扔下去, 可以链式处理
\(\rm{C}\)
思路
题意
给定一个正整数
在一次操作中, 你可以向 添加任何只包含数字 的正整数, 该数字可以重复多次
为了使数字 在其十进制表示中至少包含一个数字 , 所需的最小操作次数是多少
答案上界
发现一直在个位加上 , 无论什么情况都可以在 次之内解决
所以答案上界确定
但好像没有什么用啊
一次操作只有 \(9\) 种情况, 直接乱搜即可
代码
#include <bits/stdc++.h>
#define int long long
int ans;
int pow10[12];
int p[12];
bool check(int now) {
while (now) {
if (now % 10 == 7) return true;
now /= 10;
}
return false;
}
bool flag;
void dfs(int now, int tmp, int lst) {
if (now > 10) return;
for (int i = lst; i >= 0; i--) if ((p[now] + tmp + i * 9) % 10 == 7) { flag = true; return; }
for (int i = lst; i >= 0; i--) {
dfs(now + 1, (p[now] + tmp + i * 9) / 10, i);
}
}
void solve() {
ans = 8;
int n; scanf("%lld", &n);
int cnt = 0;
memset(p, 0, sizeof p);
if (check(n)) { printf("0\n"); return; }
while (n) {
p[++cnt] = n % 10;
n /= 10;
}
for (int ans = 1; ans <= 8; ans++) {
if ((p[1] + 0 + ans * 9) % 10 == 7) {
printf("%lld\n", ans); return;
}
flag = false;
dfs(2, (p[1] + 0 + ans * 9) / 10, ans);
if (flag) { printf("%lld\n", ans); return; }
}
}
signed main()
{
pow10[0] = 1; for (int i = 1; i <= 10; i++) pow10[i] = pow10[i - 1] * 10;
int t; scanf("%lld", &t);
while (t--) solve();
return 0;
}
总结
两种乱搞题
- 数据范围小的
- 答案范围小的

浙公网安备 33010602011771号