小凯的疑惑

GitHub跳转原题关系图返回列表

互素两币值凑不出的最大价值是数论中的 Frobenius 数:按模 a 分余数类,每类的最小可达值最大为 (a-1)b,直接得公式 ab-a-b。

OJ: roj

题目 ID: 3648

难度:普及

标签:数论数学

创建: 2026-10-02 12:46

更新: 2026-10-06 16:00

题目描述

小凯手中有两种面值互素的金币,面值为正整数 a,ba, b(1≤a,b≤1091 \le a, b \le 10^9),每种都有无数个。在不找零的情况下,有些价值他无法准确支付,输入数据保证这样的价值存在。输入格式:一行两个正整数 a,ba, b,用一个空格隔开;输出格式:一个正整数 NN,表示不能准确支付的最贵物品的价值。样例:输入 3 7,输出 11(凑不出的是 1,2,4,5,8,111, 2, 4, 5, 8, 11,最大为 1111)。

思路

经典 Frobenius 数(Chicken McNugget 定理):互素两币值凑不出的最大价值为 ab−a−bab - a - b。按模 aa 分余数类,每类的可凑出数由其最小可达值 yrby_r b(yry_r 为使 yrb≡r(moda)y_r b \equiv r \pmod a 的最小非负 yy)加任意多个 aa 构成,yry_r 最大取 a−1a-1,故该类凑不出的最大数为 (a−1)b−a(a-1)b - a,即答案。正确性两半成立:ab−a−bab-a-b 本身凑不出(模 aa 导出 y≡−1y \equiv -1 与 0≤y≤a−10 \le y \le a-1 矛盾),更大的数按余数取合适的 yy 即可凑出。

参考代码

Python 版:

python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-10-02 12:46
# update_at: 2026-10-02 12:46

import sys


def solve() -> None:
    a, b = map(int, sys.stdin.buffer.read().split())
    # 互素两币值不能凑出的最大值 = a*b - a - b(数论结论,证明见题解)
    print(a * b - a - b)


if __name__ == "__main__":
    solve()

C++ 版(同一算法):

cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-10-06 16:00
 * update_at: 2026-10-06 16:00
 */
#include <cstdio>

typedef long long ll;

int main() {
    ll a, b; // 两种金币的面值,互素,最大 1e9,乘积约 1e18 需要 ll
    scanf("%lld %lld", &a, &b);
    // Frobenius 数:互素两币值凑不出的最大价值是 a*b - a - b
    printf("%lld\n", a * b - a - b);
    return 0;
}