题目描述
小凯手中有两种面值的金币,两种面值均为正整数且彼此互素。每种金币小凯都有 无数个。在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付的。现在小 凯想知道在无法准确支付的物品中,最贵的价值是多少金币?注意:输入数据保证存在 小凯无法准确支付的商品。
输入输出格式
输入格式:
输入数据仅一行,包含两个正整数 a 和 b,它们之间用一个空格隔开,表示小凯手 中金币的面值。
输出格式:
输出文件仅一行,一个正整数 N,表示不找零的情况下,小凯用手中的金币不能准确支付的最贵的物品的价值。
这次的noip,,,考场上好不容易花了两个小时推出了扩欧写法并且自己做了严格证明,结果出了考场发现这题结论a*b-a-b就是正确答案,,,
感觉自己被小学奥数秀到了,,,
好下面先上代码
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
ll a,b,x,y;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b) {x=1;y=0;return a;}
ll c=exgcd(b,a%b,y,x);
y-=a/b*x;
return c;
}
int main()
{
// freopen("math.in","r",stdin);
// freopen("math.out","w",stdout);
cin>>a>>b;
ll gcd=exgcd(a,b,x,y);
x=(x+b)%b; y=(y+a)%a;
cout<<(x-1)*a+(y-1)*b-1;
return 0;
}
下面开始证明;
我们可以考虑找到一个数k,使k无论如何都无法减去一个‘ax+by’形式的1(也就是说,这个数拆成ax+by形式之后,无论是怎么减都不能减去另一个值等于1的‘ax+by’)【说不太懂,大家仔细想一想】,那么我们只需要找一个最大的数k,然后这个k减1就是我们要找的答案;
那么这个k最大可能是多少呢,很容易想到,用最小的正整数解x减去1作为a的系数加上最小的正整数解y减去1作为b的系数,这样得出来的k,就是我们要找的无论如何都不能减去1的这么一个数,所以说用这个k再减去一个1,得到的就是我们要找的答案啦;
可能讲的不是很清晰,各位大佬多想一想应该就明白啦