AtCoder Regular Contest 112 B
Solution
考虑刚刚好使用 C C C 元
当钱数为 C C C 时,考虑这样一个特殊序列,对数 B B B 做任意次减一操作之后,在乘上 − 1 -1 −1 的结果
- 如果我们乘上奇数次 − 1 -1 −1 ,最终每一次减法都会在 B B B 上造成加 1 1 1 的贡献
- 如果我们乘上偶数次 − 1 -1 −1 ,最终每一次减法都会在 B B B 上造成减 1 1 1 的贡献
当钱数 C C C 为奇数时,可以将 C C C 表示为 C = 2 n + 1 C=2n+1 C=2n+1 的形式,考虑尽量少的乘法操作得到的边界值更优,所以我们可以得到 B B B 的范围
- 一开始进行 n n n 次减法操作得到 B − n B-n B−n,再进行乘法操作得到 − B + n -B+n −B+n
- 一开始进行乘法操作得到 − B -B −B ,再进行 n n n 次减法操作得到 − B − n -B-n −B−n
当钱数 C C C 为偶数时,可以将 C C C 表示为 C = 2 n C=2n C=2n 的形式,考虑尽量少的乘法操作得到的边界值更优,所以我们可以得到 B B B 的范围
- 当 C = 0 C=0 C=0 时,只能得到 B B B
- 当
C
>
0
C>0
C>0 时
- 如果只进行减法操作,得到 B − n B-n B−n
- 如果使用一次乘法操作,根据 C C C 为奇数时的做法,得到答案在 B − n + 1 B-n+1 B−n+1 和 B + n − 1 B+n-1 B+n−1
对于原问题,所有能用 C = k C=k C=k 元得到的数,可以用 C = k + 2 C=k+2 C=k+2 元得到。那么,我们就只要考虑 C = k C=k C=k 和 C = k − 1 C=k-1 C=k−1 两种情况,其他在他们之间的数都能得到。
设 C C C 元得到的数为, a , b a,b a,b , C − 1 C-1 C−1 元得到的数为 c , d c,d c,d,那么得到的所有数就是 [ a , b ] [a,b] [a,b] 和 [ c , d ] [c,d] [c,d] 的元素个数和减去重复元素的个数 0 0 0 或者 m i n ( b , d ) − m a x ( a , c ) min(b,d)-max(a,c) min(b,d)−max(a,c) (画图可知)
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
pair<ll, ll> exact(ll B, ll C) {
ll n = C / 2;
if (C % 2 != 0) return {-B - n, -B + n};
else {
if (C == 0) return {B, B};
else {
return {B - n, B + n - 1};
}
}
}
int main() {
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
// ios::sync_with_stdio(false);
ll B, C;
cin >> B >> C;
ll ans;
// pair<ll, ll> ab;
// pair<ll, ll> cd;
// ab = exact(B, C);
// cd = exact(B, C - 1);
// ll a, b, c, d;
// a = ab.first, b = ab.second, c = cd.first, d = cd.second;
// C++ 17
const auto [a, b] = exact(B, C);
const auto [c, d] = exact(B, C - 1);
ans = (b - a + 1) + (d - c + 1) - max((ll) 0, min(b, d) - max(a, c) + 1);
cout << ans << '\n';
return 0;
}
这篇博客探讨了如何在AtCoder Regular Contest 112B问题中,运用数学策略来处理涉及减法和乘法操作的货币系统。作者分析了不同数额货币下最优操作的边界值,并通过奇偶性判断来确定可能的数值范围。文章还提供了C++代码实现,展示了如何计算给定金额下可能得到的所有数值的个数。
1011

被折叠的 条评论
为什么被折叠?



