Uva10090 Marbles 扩展欧几里德的应用

来源:互联网 发布:网络负面处理公司 编辑:程序博客网 时间:2024/04/29 01:56

好几天没有做题目了,因为心情不好导致刷题没动力,现在感觉还可以,继续数论的路,为了回顾一下扩展欧几里德所以做了一下这个题目, 根据题目意思 很容易找到方程 n1*x0+n2*y0=n,求解,我们都知道扩展欧几里德求出的x0,y0事实上是有通解的,

x0*n1+y0*n2=gcd(n1,n2)的通解,

x = x0 + n2/Gcd(n1, n2) * t
y = y0 - n1/Gcd(n1, n2) * t(其中t为任意整数)
方程 x0*n1+y0*n2=n的通解
x= x1 + n2/Gcd(n1,n2) * t
y = y1 - n1/Gcd(n1,n2) * t(其中t为任意整数)

因为x0,y0都是要大于等于0的,所以我们可以找到t的范围,由此变简单了

#include<iostream>#include<cstdio>#include<list>#include<algorithm>#include<cstring>#include<string>#include<queue>#include<stack>#include<map>#include<vector>#include<cmath>#include<memory.h>#include<set>#define ll long long#define eps 1e-8#define inf 0xfffffffconst ll INF = 1ll<<61;using namespace std;//vector<pair<int,int> > G;//typedef pair<int,int> P;//vector<pair<int,int>> ::iterator iter;////map<ll,int>mp;//map<ll,int>::iterator p;//ll exgcd(ll a,ll &x,ll b,ll &y){if(b==0){x=1;y=0;return a;}ll r=exgcd(b,x,a%b,y);ll t=x;x=y;y=t-a/b*y;return r;}int main(){ll n,c1,n1,c2,n2;while(scanf("%lld",&n),n){scanf("%lld %lld",&c1,&n1);scanf("%lld %lld",&c2,&n2);ll x0,y0;ll gcd=exgcd(n1,x0,n2,y0);if(n%gcd!=0)puts("failed");else{x0=x0*n/gcd;y0=y0*n/gcd;ll ans1,ans2;n1=n1/gcd;n2=n2/gcd;if(n2*c1 >= n1*c2){ll t=-x0/n2;if(x0%n2!=0 && x0<0)t++;ans1=x0+t*n2;ans2=y0-t*n1;}else{ll t=y0/n1;if(y0%n1!=0 && y0<0)t--;ans1=x0+t*n2;ans2=y0-t*n1;}if(ans1 < 0 || ans2 < 0)puts("failed");elseprintf("%lld %lld\n",ans1,ans2);}}}




原创粉丝点击