题目大意:求ax+by=1的非负整数x和y(x最小)
思路:简单的扩展欧几里得
1、ax+by=c若有解(x0,y0),则必有(a,b)|c , 其中(a,b)表示a,b的最大公约数,可以整除c则有解。
2、若(a,b)=1 , 则方程全部解为:x=x0+bt ,y=y0-at(t为整数)
3、若(a,b)> 1 , 则方程全部解为:x=x0+bt/d ,y=y0-at/d , d=(a,b);
扩展欧几里得可以求出a,b最大公约数d,还可以求出|x|+|y|最小值得x,y的解。
#include <cstdio>
#include <string>
#include <cstring>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <iomanip>
#include <iostream>
#include <sstream>
using namespace std;
#define maxn 1000003
#define MOD 1000000007
#define mem(a , b) memset(a , b , sizeof(a))
#define LL __int64
LL a ,b;
LL gcd(LL a , LL b)
{
if(b == 0) return a;
else return gcd(b , a%b);
}
void gcd2(LL a , LL b , LL &d ,LL &x , LL &y)
{
if(!b)
{
d = a;
x = 1 ;
y = 0;
}
else
{
gcd2(b , a%b , d , y , x);
y -= x*(a/b);
}
}
int main()
{
while(scanf("%I64d %I64d" , &a , &b) != EOF)
{
LL d , x , y;
LL g = gcd(a , b);
if(g != 1)
{
printf("sorry\n");
continue;
}
gcd2(a , b , d , x , y);
x /= d;
y /= d;
LL t1 = b / d;
LL t2 = a / d;
x = (x % t1 + t1) % t1; //找到最小正整数x
y = (1 - a * x) / b; //对应的y;
printf("%I64d %I64d\n" ,x , y);
}
/* std::string name("12345 56789 56789");
string age = "27";
stringstream os;
os << name;
while(os >> age)
// age = 12345
cout<<age<<endl;*/
return 0;
}