欧几里德
ax+by=gcd(a,b)与ax+by=c 模版
1 LL ext_gcd(LL a,LL b,LL& x,LL& y){ //解 ax+by=gcd(a,b);
2 LL t,ret;
3 if (!b){
4 x=1,y=0;
5 return a;
6 }
7 ret=ext_gcd(b,a%b,x,y);
8 t=x,x=y,y=t-a/b*y;
9 return ret;
10 }
11 LL ext(LL a,LL b,LL c){ //解 ax+by=c
12 LL x, y;
13 LL gcd=ext_gcd(a,b,x,y);
14 if(c%gcd) { //当c不为gcd(a,b)的倍数时,即无整数解
15 cout<<"failed"<<endl;
16 return 0;
17 }
18 x*=c/gcd; y*=c/gcd;
19 LL dx=b/gcd,dy=a/gcd; //x=x+i*dx ,y=y-i*dy;
20 //求 x>=0&& y>=0时 i可取的范围 [low,up] ;
21 LL low=ceil(-x/(double)dx);
22 LL up=floor(y/(double)dy);
23
24 if(low>up) cout<<"failed"<<endl; //当 low>up (即上界大于下界)不存在整数解
25 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstring> #include <cstdio> #include<string> #include<queue> #include<vector> #include<map> #include <set> #include<ctime> #include<cmath> #include <cstdlib> #include<algorithm> using namespace std; #define LL long long LL ext_gcd(LL a,LL b,LL& x,LL& y){ //该算法得到的 x 和 y 即是绝对值和最小的 LL t,ret; if (!b){ x= 1,y= 0; return a; } ret=ext_gcd(b,a%b,x,y); t=x,x=y,y=t-a/b*y; return ret; } int main(){ LL a,b; while(scanf("%lld%lld",&a,&b)!=EOF){ LL x,y; LL gcd=ext_gcd(a,b,x,y); printf("%lld %lld %lld\n",x,y,gcd); } }
uva 10090 - Marbles
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstring> #include <cstdio> #include<string> #include<queue> #include<vector> #include<map> #include <set> #include<hash_set> #include<ctime> #include<cmath> #include <cstdlib> #include<algorithm> using namespace std; #define LL long long #define nMAX (1<<10+10) #define mMAX 110 LL n,n1,n2,c1,c2; LL ext_gcd(LL a,LL b,LL& x,LL& y){ //解 ax+by=gcd(a,b); LL t,ret; if (!b){ x=1,y=0; return a; } ret=ext_gcd(b,a%b,x,y); t=x,x=y,y=t-a/b*y; return ret; } LL ext(LL a,LL b,LL c){ //解 ax+by=c LL x, y; LL gcd=ext_gcd(a,b,x,y); if(n%gcd) { cout<<"failed"<<endl; return 0; } x*=c/gcd; y*=c/gcd; LL dx=b/gcd,dy=a/gcd; LL low=ceil(-x/(double)dx); LL up=floor(y/(double)dy); if(low>up) cout<<"failed"<<endl; else { if(c1*n2<=c2*n1){ x=x+up*dx; y=y-up*dy; }else { x=x+low*dx; y=y-low*dy; } cout<<x<<" "<<y<<endl; } return gcd; } int main(){ while(cin>>n&&n){ cin>>c1>>n1>>c2>>n2; ext(n1,n2,n); } }
zoj 3593 One Person Game
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstring> #include <cstdio> #include<string> #include<queue> #include<vector> #include<map> #include <set> #include<ctime> #include<cmath> #include <cstdlib> #include<algorithm> #include <iomanip> #include <bitset> using namespace std; #define LL long long const LL MAX = 1<<25; const LL nMAX =50; const LL INF =(((1LL)<<63)-1); const LL MOD= 1000000007; LL ans; LL ext_gcd(LL a,LL b,LL& x,LL& y){ LL t,ret; if (!b){ x=1,y=0; return a; } ret=ext_gcd(b,a%b,x,y); t=x,x=y,y=t-a/b*y; return ret; } LL ext(LL a,LL b,LL c){ LL x,y; LL gcd=ext_gcd(a,b,x,y); if(c%gcd) { return 0; } x*=c/gcd; y*=c/gcd; LL dx=b/gcd,dy=a/gcd; //x=x+i*dx ,y=y-i*dx; //求 x>=0&& y>=0时 i可取的范围 [low,up] ; LL low=floor(-x/(double)dx); LL up=ceil(y/(double)dy); ans=min((LL)(abs(x)+abs(y)),ans); ans=min((LL)(abs(x+low*dx)+abs(y-low*dy)),ans); ans=min((LL)(abs(x+up*dx)+abs(y-up*dy)),ans); low=ceil(-x/(double)dx); up=floor(y/(double)dy); ans=min((LL)(abs(x)+abs(y)),ans); ans=min((LL)(abs(x+low*dx)+abs(y-low*dy)),ans); ans=min((LL)(abs(x+up*dx)+abs(y-up*dy)),ans); return 1; } int main(){ LL A,B,a,b,T; scanf("%lld",&T); while(T--){ scanf("%lld%lld%lld%lld",&A,&B,&a,&b); if(A>B) swap(A,B); ans=INF; ext(a,b,B-A); ext(a+b,b,B-A); ext(a+b,a,B-A); if(ans!=INF) printf("%lld\n",ans); else printf("-1\n"); } }