分析:
首先看完这个题,我瞬间想到了我小学时做的奥数题。。。。。。
然后我翻了翻,发现没有做错题。。。。。。
咳咳,进入正题:
这个题首先基本没有什么思路,按照以往的做法,我们模拟一下数据+自造数据找规律。
事实证明,完全是可以的。
这个题的考点就是数论(gcd,exgcd)
什么gcd,exgcd具体做法其余dalao们已经讲的很清楚了,我这个蒟蒻简单叨叨几句:
拓展欧几里得算法:
一定存在整数a,b,使得ax+by=(x,y)
欧几里得算法:gcd(x,y)->gcd(y,x%y)
gcd(x,y)->gcd(y,x-⌊x/y⌋*y)
如果已知a’y+b’(x- ⌊x/y⌋ *y)=(x,y)
整理得b’x+(a’-b’⌊x/y⌋)y=(x,y)
最底层:x’=(x,y) y’=0
显然有1x’+0y’=(x,y)
于是可以递归求出a,b
拓展欧几里得算法告诉我们x与y的线性组合的取值可以是(x,y),那么自然(x,y)的整数倍也能够被取到。/
Thm: x与y的线性组合能且仅能取(x,y)的整数倍
那线性组合又是什么?
Def:∀a,b∈Z ax+by为x与y的一个线性组合
那么x与y的线性组合可能取到哪些值?
设k=(x,y), p=ax+by
p=k(ax/k+by/k)
p是k的整数倍!
x与y的线性组合的取值只能是x与y的gcd的整数倍
话不多说,上代码:
#include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<iostream> #define LL long long //比较懒。。。。 using namespace std; LL exgcd(LL x,LL y,LL &a,LL &b) //扩展欧几里得的核心算法 { if(y==0) {a=1;b=0;return x;} LL aa,bb,ans; ans=exgcd(y,x%y,aa,bb); a=bb; b=aa-bb*(x/y); return ans; } int main() { LL a,b,pa,pb,g; cin>>a>>b; g=exgcd(a,b,pa,pb); //一轮exgcd操作 a/=g;b/=g; LL t=pa/b; pa-=t*b;pb+=t*a; while(pa>0) pa-=b,pb+=a; //处理最小值 while(pa-b>=0) pa-=b,pb+=a;//(同上) cout<<g<<endl<<-pa<<' '<<pb; return 0; }
最后默默吐槽:格式错误3次,我WA声都要听烦了。。。。
来源:https://www.cnblogs.com/RiaOIer-Blog/p/12288023.html