codeforce 787A The Monster 兩種解法
阿新 • • 發佈:2018-12-09
題意 : 問b+na = d+kc,有無解;
b-d = kc - na;
#include <bits\stdc++.h>
using namespace std;
int gcd(int a,int b){
return b == 0? a:gcd(b,a%b);
}
int main(){
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
if( b < d){
swap(b,d);swap(a,c);
}
int xx = gcd(a,c);
if((b-d) % xx != 0){
printf("-1\n");
}
else{
for(int i=0;;i++){
if((b+i*a-d )% c == 0){
printf("%d\n",b+i*a);
break;
}
}
}
return 0;
}
擴充套件歐幾里德
b-d = kc - na; 則有 Ax + By = c,B<0; 通過 擴充套件歐幾里德演算法 可以得到一組 解:(x,y) if(x < 0 || y <0) 則x,y 就都增加: x += B/gcd;y -= A/gcd; 否則,就減少。這麼考慮的話,gcd要為正數。所以當gcd為負數時 (-x,-y) 是 A(-x) + B(-y) = -gcd 的解。
#include <bits\stdc++.h>
using namespace std;
typedef int li ;
li ex_gcd(li a, li b, li& x, li& y) {
if (!a) {
x = 0, y = 1;
return b;
}
li xx, yy, g = ex_gcd(b % a, a, xx, yy);
x = yy - b / a * xx;
y = xx;
return g;
}
int main(){
int a,b,c,d; cin>>a>>b>>c>>d;
if (b<d){
swap(a,c);
swap(b,d);
}
int A = c, B = -a, C = b-d;
int x,y;
int gcd = ex_gcd(A,B,x,y);// Ax + By = C
if(C%gcd!=0){
cout<<"-1\n";return 0;
}
if(gcd < 0){
gcd = -gcd;
x = -x;
y = -y;
}
//cout<<x<<" "<<y<<endl;
//cout<<A*x+B*y<<" "<<gcd<<endl;
x = C*x/gcd; y = C*y/gcd;// 如果只逆轉 gcd 的話, 則此處求一組解就會出錯。
// cout<<A*x+B*y<<" "<<C<<endl;
int flag = 0;
if(x < 0 || y <0) flag = 1;
for(int i=1;;i++){
if(!flag){
x += B/gcd;
y -= A/gcd;
}
else {
x -= B/gcd;
y += A/gcd;
//cout<<x<<" "<<y<<endl;
}
if(flag){
if(x>=0&&y>=0){
printf("%d\n",A*x+d);
break;
}
}
else{
if(x < 0 ){
x -= B/gcd;
printf("%d\n",A*x+d);
break;
}
if(y < 0){
y += A/gcd;
printf("%d\n",-B*y+b);
break;
}
}
}
return 0;
}
對上一種優化:第一個 x>=0,y>=0 即為所求的解。所以可以直接求出。
x = x0 + B/gcd*t , y = y0 - A/gcd*t;
#include <bits\stdc++.h>
using namespace std;
typedef int li ;
li ex_gcd(li a, li b, li& x, li& y) {
if (!a) {
x = 0, y = 1;
return b;
}
li xx, yy, g = ex_gcd(b % a, a, xx, yy);
x = yy - b / a * xx;
y = xx;
return g;
}
int main(){
int a,b,c,d; cin>>a>>b>>c>>d;
if(b<d){
swap(a,c);
swap(b,d);
}
int A = c, B = -a, C = b-d;
int x,y;
int gcd = ex_gcd(A,B,x,y);// Ax + By = C
if(C%gcd!=0){
cout<<"-1\n";return 0;
}
if(gcd < 0){
gcd = -gcd;
x = -x;
y = -y;
}
//cout<<x<<" "<<y<<endl; // 0 -1
//cout<<gcd<<endl;
x = C*x/gcd; y = C*y/gcd;
//cout<<x<<" "<<y<<endl;
int flag = 0;
int k1 = B/gcd , k2 = A/gcd;
if(k1 < 0) k1 = -k1;
if(k2 < 0) k2 = -k2;
//cout<<k1<<" "<<k2<<endl;
int t = x/k1;
x -= t*k1, y -= t*k2;
if( x < 0){
x += k1, y+=k2;
}
// cout<<x<<" "<<y<<endl;
if( y < 0){
t = y/k2;
x -= t*k1, y -= t*k2;
if( y < 0){
x += k1, y+=k2;
}
}
printf("%d\n",A*x+d);
return 0;
}