1931(925div3)
A. Recovering a Small String
void solve() {
int n;cin >> n;
for (int i = 'a';i <= 'z';i++) {
for (int j = 'a';j <= 'z';j++) {
for (int k = 'a';k <= 'z';k++) {
if (i + j + k - 'a' * 3 + 3 == n) {
cout << char(i) << char(j) << char(k) << '\n';return;
}
}
}
}
}
B. Make Equal
给出一个数组,其之和一定是
void solve() {
int n, sum = 0; cin >> n;
vector<int> a(n);
for (auto& i : a)cin >> i, sum += i;
int eq = sum / n,cnt = 0;
bool ok = true;
for (int i = 0;i < n;i++) {
if (a[i] >= eq) {
cnt += a[i] - eq;
} else {
cnt -= eq - a[i];
if (cnt < 0)ok = false;
}
}
if (ok) {
cout << "yes\n";
} else {
cout << "no\n";
}
}
C. Make Equal Again
只能执行一次操作,给定区间加上任意值,求最少的区间长度
就看两边的就行
void solve() {
int n;cin >> n;vector<int> a(n);
for (auto& i : a)cin >> i;
int cnt1 = 1, cnt2 = 1;
for (int i = 1;i < n;i++) {
if (a[i] == a[i - 1]) {
cnt1++;
} else break;
}
for (int i = n - 1;i >= 0;i--) {
if (a[i] == a[i - 1]) {
cnt2++;
} else break;
}
if (cnt1 == cnt2 && cnt1 == n) {
cout << 0 << '\n';return;
}
if (a[0] == a[n - 1]) {
cout << n - (cnt1 + cnt2) << '\n';
} else {
cout << n - max(cnt1, cnt2) << '\n';
}
}
D. Divisible Pairs
给出一个数组
Solution
易得:
存下
void solve() {
int n, x, y;cin >> n >> x >> y;
vector<int> a(n);
for (auto& i : a)cin >> i;
ll cnt = 0;
map<pair<int, int>, int> mod;
for (int i = 0;i < n;i++) {
cnt += mod[{(x - a[i] % x) % x, a[i] % y}];
mod[{a[i] % x, a[i] % y}]++;
}
cout << cnt << '\n';
}
或
void solve() {
int n, x, y;cin >> n >> x >> y;
vector<int> a(n);
for (auto& i : a)cin >> i;
ll cnt = 0;
map<pair<int, int>, int> mod;
for (int i = 0;i < n;i++) {
mod[{a[i] % x, a[i] % y}]++;
}
for (int i = 0;i < n;i++) {
--mod[{a[i] % x, a[i] % y}];
cnt += mod[{(x - a[i] % x) % x, a[i] % y}];
++mod[{a[i] % x, a[i] % y}];
}
cout << cnt / 2 << '\n';
}
E. Anna and the Valentine's Day Gift
给出一个长度为
- Anna 选择一个
,去掉前导 0 - Sasha 选择
当 Anna 下完棋且数组中只剩下一个元素的时候,游戏结束,如果剩下的数字
双方都以最佳方式玩游戏,输出获胜方。
Solution
博弈论
容易发现,Anna 每次优先翻转 后导 0 最多的数
,Sasha 每次优先以 有最多后导 0 的数
作为
以
- Anna:
Sasha: - Anna:
Sasha: - Anna:
Sasha: - Anna:
, Sasha WIN
即每次 Anna 删除一个最多的,Sasha 保留一个第二多的,以此类推。
比较简单。
void solve() {
int n, m;cin >> n >> m;
vector<pair<int, int>> a(n);for (auto& [i, j] : a)cin >> j;
int sum = 0;
for (int i = 0;i < n;i++) {
string num = to_string(a[i].second);
sum += num.size();
int cnt = 0;
for (int i = num.size() - 1;i >= 0;i--) {
if (num[i] == '0')cnt++;
else break;
}
a[i].first = cnt;
}
sort(a.begin(), a.end());
for (int i = n - 1;i >= 0;i -= 2) {
sum -= a[i].first;
}
if (sum - 1 >= m)cout << "Sasha\n";
else cout << "Anna\n";
}
F. Chat Screenshots
编程竞赛聊天室有
例如,有
st 看到的顺序是 。 nd 用户看到的订单是 。 rd 用户看到的顺序是 。 th 用户看到订单 。
你的任务是确定所有截图是否都有一定的顺序。
Solution
拓扑排序
按照题意:每个人截图后的
void solve() {
int n, k;cin >> n >> k;
vector<int> g[n + 1], du(n + 1, 0);
for (int i = 0;i < k;i++) {
vector<int> a(n);
for (int j = 0;j < n;j++) {
cin >> a[j];
}
for (int j = 1;j < n - 1;j++) {
g[a[j]].push_back(a[j + 1]);
du[a[j + 1]]++;
}
}
queue<int> q;
for (int i = 1;i <= n;i++) {
if (!du[i])q.push(i);
}
while (q.size()) {
int t = q.front();q.pop();
for (auto i : g[t])
if (!--du[i])q.push(i);
}
for (int i = 1;i <= n;i++) {
if (du[i]) {
cout << "NO\n";return;
}
}
cout << "YES\n";
}
G. One-Dimensional Puzzle
每种类型包含
Solution
组合数 (隔板法)
Codeforces Round 925 (Div. 3) A-G 比赛录屏+讲解(60分钟开始)_哔哩哔哩_bilibili
注意:本题写的
前置小练习:
将 10 个相同的小球放入 8 个盒子里(每个盒子至少有一个小球),有多少种放法? 插空法:10 个小球有 9 个空可以插,有 7 个隔板, (即两块板之间不能相邻且第一块板左侧与最后一块板右侧必须有球)。
则答案
将 10 个相同的小球放入 8 个盒子里 (盒子可以为空),有多少种放法? 隔板法:10 个小球和 7 个隔板,可以组成一个由 17 个物件的排列,从中选择 7 个位置放置隔板,这样就可以把小球分配到 8 个盒子中
答案:
求 有多少个正整数解? 即在
中选择 3 个空插入,答案:
求 有多少个非负整数解? 法一:可以变换一下思路:这时的
,将等式两边同时加上 4,则 求 的正整数解 法二:将 3 个隔板和 10 组成一个 13 件物品的排列,选择 3 个位置放置隔板
答案:
则可以抽象:
求
将
可以在
放在 和 之间 放在 和 之间
本题目插入的意思 ,设空位个数为
- 将
放到 个空位空位中 (可以为空)的方法个数 非负整数解个数
下面的个数为
当
空位: 空位:
方案数:
当
空位:
方案数:
当
空位:
方案数:
然后就是预处理与逆元(本处为线性递推,快速幂也可)的计算。(待更
const int mod = 998244353, N = 2e6 + 10;
ll fac[N], jv[N], inv[N];
void init(int n) {
jv[0] = fac[0] = 1;
for (int i = 1;i <= n;i++) {
inv[i] = i == 1 ? 1 : (mod - mod / i) * inv[mod % i] % mod;
fac[i] = fac[i - 1] * i % mod;
jv[i] = jv[i - 1] * inv[i] % mod;
}
}
ll C(int m, int n) {
if (n < m || m < 0) return 0;
return fac[n] * jv[n - m] % mod * jv[m] % mod;
}
void solve() {
int a, b, c, d;cin >> a >> b >> c >> d;
if (abs(a - b) >= 2) {
cout << 0 << '\n';return;
}
ll ans = 0;
if (!a && !b)ans = c == 0 || d == 0;
else if (a == b) {
ans = (C(a - 1, a + c - 1) * C(a, a + d) % mod + C(a, a + c) * C(a - 1, a + d - 1) % mod) % mod;
} else if (a == b - 1) {
ans = C(a, a + c) * C(a, a + d) % mod;
} else if (a == b + 1) {
ans = C(a - 1, a + c - 1) * C(a - 1, a + d - 1) % mod;
}
cout << ans << '\n';
}
main::init(2e6);