题意:
用 a, b 两种面额的硬币去组成更大面额的钱,问哪个面额之后的所有数字都可被组成
例:a = 5, b = 7, 此时 23 之后的数字都可被连续组成, 24 = 5 * 2 + 7 * 2, 25 = 5 * 5, 26 = 5 * 1 + 7 * 3...
解题思路:
(怎么说,我的做法属于碰运气的类型,有个初步的猜想觉得差不多了就去写了写
而这道题事实上是可以推出公式的,正经做法参见 大佬)
因为所有数字都可被连续的构成,那么必有
a * x1 + b * y1 = n
a * x2 + b * y2 = n + 1
故必有
a * x3 + b * y3 = 1 ……(*)
因为 a 与 b 互质,由扩展欧几里得知,(*)式必有解
对转移过程有意义的两组解分别是(1) x1 > 0, y1 < 0 (满足x的最小性) (2) x2 < 0, y2 > 0 (满足y的最小性)
也就是说,第一个开始连续的数字必定不能通过(*)式转移过来,所以第一个连续的数字即为 (x1 - 1) * a + (y2 - 1) * b
还是上面的例子,
a * x + b * y = 1
当a = 5, b = 7, 两组解分别为 (1) x1 = 3, y1 = -2 (2) x2 = -4, y2 = 3
24 的解组为 2 2
加上(1), 得到 5 0,即为 25 的解组
加上(2), 得到 1 3,即为 26 的解组
加上(1), 得到 4 1,即为 27 的解组
……
然而24的解组就不能通过其他任何正整数解组通过加上(1)或(2)转移得到,那么必然有 x < x1, y < y2,
然后自然而然地就猜想第一个连续的数是 (x1 - 1) * a + (y2 - 1) * b
所以答案就是 (x1 - 1) * a + (y2 - 1) * b - 1
其实这里面有挺多gap的,比如说为什么就能保证这之后一定都连续?
为什么不是 x - 2?
这就是直觉啊
其实就是碰运气
其实就是瞎搞
还是有教训的,比如说这种瞎搞的做法,一旦第一遍交了没过,就很容易动摇...毕竟没有坚实的理论基础
然而后来发现自己mod了1e9+7而题目里面压根没有这个要求(??? 十分糟心
AC代码如下:
#include <cstdio>
#include <cstring>
typedef long long LL;
int x, y;
void exgcd(int x, int y, int& x1, int& y1) {
if (y == 0) { x1 = 1; y1 = 0; return; }
exgcd(y, x % y, x1, y1);
int temp = x1;
x1 = y1;
y1 = temp - x / y * y1;
}
void work() {
int x1, y1;
exgcd(x, y, x1, y1);
// printf("%d %d\n", x1, y1);
LL ans;
if (x1 < 0) {
int x2 = x1 + y;
ans = (LL)(x2 - 1) * x + (LL)(y1 - 1) * y;
}
else {
int y2 = y1 + x;
ans = (LL)(x1 - 1) * x + (LL)(y2 - 1) * y;
}
printf("%lld\n", ans - 1);
}
int main() {
int T;
scanf("%d\n", &T);
while (scanf("%d%d", &x, &y) != EOF) work();
return 0;
}