您的位置:首页 > 其它

Uva10090 Marbles 扩展欧几里德的应用

2013-12-08 19:18 405 查看
好几天没有做题目了,因为心情不好导致刷题没动力,现在感觉还可以,继续数论的路,为了回顾一下扩展欧几里德所以做了一下这个题目, 根据题目意思 很容易找到方程 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 0xfffffff
const 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");
else
printf("%lld %lld\n",ans1,ans2);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: