题意:给定a, b且gcd(a, b) = 1, 找到一个最小的正整数k, 使得方程ax+by=k无非负整数解。
思路:
- 根据题意得,可以转换为找到一个正整数k,k可以用ax+by表示而k-1不可以
- 则一定存在非负整数x,y,满足ax+by=k(x>=0, y>=0)
- 先考虑这个方程ax+by=gcd(a,b) = 1;
- 令x1, y1为此方程x为非负整数且最小的一组解 ax1 + bx1 = 1
- 令x2, y2为此方程y为非负整数且最小的一组解 ax2 + bx2 = 1
- 那么将ax+by=k减去这两个式子,得到:
a(x - x1)+b(y - y1) = k-1;
a(x - x2)+b(y - y2) = k-1;
- 这时候,如果(1)式x-x1<0或y-y1<0、(2)式x-x2<0或y-y2<0,这样k-1就没办法被表示出来了
- 考虑到x1>0,x2<0,y1<0,y2>0,且x>=0, y>=0, 那么x-x1和y-y2小于0.为了让k-1尽可能大,那么x-x1和y-y2恰取-1是最优的。
- 移项得:
x = x1-1, y = y2-1
- 将x, y代入,a(x1-1)+b(y2-1)=k
- 所以题目要求的k-1就是
A(x1 - 1) + b(y2 - 1) - 1
代码:
1 #include <iostream> 2 using namespace std; 3 4 long long a, b, x, y; 5 6 int exgcd(long long a, long long b, long long &x, long long &y) 7 { 8 if(b == 0) 9 { 10 x = 1; 11 y = 0; 12 return a; 13 } 14 int r = exgcd(b, a%b, x, y); 15 int t = x; 16 x = y; 17 y = t - a / b * y; 18 return r; 19 } 20 21 int main() 22 { 23 cin >> a >> b; 24 exgcd(a, b, x, y); 25 x = (x % b + b) % b; 26 y = (y % a + a) % a; 27 cout << a * (x - 1) + b * (y - 1) - 1; 28 return 0; 29 }