poj 2142 The Balance 扩展欧几里得
2014-06-28 18:02
330 查看
首先求出通项 X=x+b/d*t Y=y-a/d*t (x,y为ax+by=gcd(a,b)的解,d=gcd(a,b))可知我们要求的最小的解是 abs([b]x+b/d*t)
+ abs(y-a/d*t)[/b]
设a>b不是的话,就交换a,b,我们发现上述关于t的方程是 |x+k1*t| + |y-k2*t|,由于a>b所以k2>k1,所以方程一开始右边减小的比左边增加的快
所以当y=k2*t的时候,减小的最多(之后右边为负数,两边都递增),所以最小值点在y=k2*t,由于误差,我们要在附近几个点找找。
+ abs(y-a/d*t)[/b]
设a>b不是的话,就交换a,b,我们发现上述关于t的方程是 |x+k1*t| + |y-k2*t|,由于a>b所以k2>k1,所以方程一开始右边减小的比左边增加的快
所以当y=k2*t的时候,减小的最多(之后右边为负数,两边都递增),所以最小值点在y=k2*t,由于误差,我们要在附近几个点找找。
#include<iostream> #include<cmath> #include<cstdio> using namespace std; typedef long long ll; ll myabs(ll a) { return a>0?a:-a; } void gcd(ll a,ll b,ll& d,ll& x,ll& y) { if(!b) {d=a;x=1;y=0;} else {gcd(b,a%b,d,y,x);y-=x*(a/b);} } ll get(ll x,ll y,ll a,ll b,ll d,ll t) { return myabs(x+b/d*t)+myabs(y-a/d*t); } int main() { ll a,b,c,d,x,y,t1,t2,ans,x1,y1; while(cin>>a>>b>>c&&(a||b||c)) { int f=1; if(a<b) {swap(a,b);f=0;} gcd(a,b,d,x,y); x=x*c/d;y=y*c/d; ll t=d*y/a; ll mins=0x3f3f3f3f3f3fll; for(ll i=t-2;i<=t+2;i++) { ans=get(x,y,a,b,d,i); if(ans<mins) { mins=ans; x1=myabs(x+b/d*i); y1=myabs(y-a/d*i); } } if(f) cout<<x1<<" "<<y1<<endl; else cout<<y1<<" "<<x1<<endl; } return 0; }
相关文章推荐
- POJ 2142:The Balance_扩展欧几里得
- poj 2142 The Balance (扩展欧几里得 数学)
- POJ 2142 The Balance 求|x|+|y|最小(扩展欧几里得)
- [POJ 2142]The Balance(扩展欧几里得)
- POJ 2142 - The Balance [ 扩展欧几里得 ]
- poj 2142 The Balance 数论-扩展欧几里得
- POJ 2142:The Balance_扩展欧几里得(多组解)
- POJ 2142 The Balance 扩展欧几里得,求|x|+|y|最小
- poj 2142 The Balance 扩展欧几里得
- POJ - 2142 The Balance(扩展欧几里得求解不定方程)
- poj 2142 The Balance(扩展欧几里得)
- POJ 2142:The Balance_扩展欧几里得
- POJ-2142-The Balance(扩展欧几里得)
- poj 2142 The Balance 扩展欧几里得
- POJ2142_The Balance_扩展欧几里得
- poj 2142 The Balance (基础扩展欧几里得)
- POJ 2142 扩展欧几里得
- POJ2142 The Balance (扩展欧几里德)
- POJ The Balance —— 扩展欧几里得
- POJ 2142 The Balance(扩展欧几里德解方程)