您的位置:首页 > 其它

欧几里得&扩展

2015-09-08 00:30 323 查看
先配上

欧几里得的模版:

// 欧几里得
//求两个数的最大公约数
int gcd(int a,int b)
{
return b==0 ? a:gcd(b,a%b);
}


扩展欧几里得的模版:

int extend_gcd(int a,int b,int &x,int &y)
{
if(b==0){
x=1;y=0;
return a;
}
else{
int r=extend_gcd(b,a%b,y,x);
y-=x*(a/b);
return r;
}
}


开始我不知道,x,y可以是负数,一直不能理解,刷了几道题看了看题解,慢慢对他有了了解和认识,但是现在还不能默写出来扩展欧几里得,只会套用。

重要的的是理解 模版的运算过程,并且自己能熟练的敲出来。

刷题:hdu1222、1576、2669

逐渐掌握扩展欧几里得算法。

下面我附上我这几道题的AC代码:

HDU1222:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
int GCD(int aa,int bb)
{
int i,t;
if(aa<bb){
t=aa;
aa=bb;
bb=t;
}
while(aa%bb!=0){
i=aa%bb;
if(bb>i){
aa=bb;
bb=i;
}
else aa=i;
}
return bb;
}

int main()
{
int p;
ll n,m;
long i,j,k;
cin >> p;
while(p--){
cin>>m>>n;
if(GCD(m,n)==1)cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
return 0;
}


获得经验:用GCD()函数,当公约数大于1时就代表安全。

HDU1576:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
int extend_gcd(ll a,ll b,ll &x,ll &y)
{
if(b==0){
x=1;y=0;
return a;
}
else{
ll r=extend_gcd(b,a%b,y,x);
y-=x*(a/b);
return r;
}
}

int main()
{
ll t,n;
ll b;
ll i,j,k;
cin>>t;
while(t--){
cin>>n>>b;
extend_gcd(b,9973,i,j);
i*=n;
i=(i%9973+9973)%9973;
cout<<i<<endl;
}
return 0;
}


灵活运用 扩展欧几里得 。

HDU2669:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
int extend_gcd(ll a,ll b,ll &x,ll &y)
{
if(b==0){
x=1;y=0;
return a;
}
else{
ll r=extend_gcd(b,a%b,y,x);
y-=x*(a/b);
return r;
}
}
int main()
{

ll a,b,i,j,k;
while(cin>>a>>b){
k=extend_gcd(a,b,i,j);
if(k==1){
while(i<0){
i+=b;
j-=a;
}
cout<<i<<" "<<j<<endl;
}
else cout<<"sorry"<<endl;
}
return 0;
}


开始没有仔细读题,忽略了,i必须为非负数。后来改正了,改正的地方利用数学,特妙。

如果两个数a,b不互质,那么不存在整数i,j使得a*i+b*j=1。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: