【題解】洛谷P2152[SDOI2009]Super GCD 高精度+更相減損術
阿新 • • 發佈:2018-12-10
題目描述
Sheng bill有著驚人的心算能力,甚至能用大腦計算出兩個巨大的數的GCD(最大公約 數)!因此他經常和別人比賽計算GCD。有一天Sheng bill很囂張地找到了你,並要求和你比 賽,但是輸給Sheng bill豈不是很丟臉!所以你決定寫一個程式來教訓他。
輸入輸出格式
輸入格式:
共兩行: 第一行:一個數。 第二行:一個數。
輸出格式:
一行,表示和的最大公約數。
輸入輸出樣例
輸入樣例#1:
12 54
輸出樣例#1:
6
說明
對於的資料,。 對於的資料,。
#pragma GCC optimize(2)
#include<cstdio>
#include<cstring>
const int N=1e4+10;
char s[N];
struct BigNum{
int len,num[N];
friend BigNum operator /(const BigNum&a,const int&b)
{
BigNum tmp=a;int num=0;
for(int i=tmp.len;i;i--)
{
num=num*10+a.num[i];
tmp.num[i]=num/b;
num%=b;
}
while(tmp.num[tmp.len]==0&&tmp.len>1)tmp.len--;
return tmp;
}
int cmp(const BigNum&b)const
{
if(len<b.len)return -1;
if(len>b.len)return 1;
for(int i=len;i;i--)
{
if(num[i]<b.num[i])return -1;
if(num[i]>b.num[i])return 1;
}
return 0;
}
friend BigNum operator -(BigNum&a,const BigNum&b)
{
BigNum tmp;tmp.len=a.len;
for(int i=1;i<=tmp.len;i++)
{
if(a.num[i]<b.num[i])a.num[i]+=10,a.num[i+1]--;
tmp.num[i]=a.num[i]-b.num[i];
}
while(tmp.num[tmp.len]==0&&tmp.len>1)tmp.len--;
return tmp;
}
friend BigNum operator *(const BigNum&a,const int&b)
{
BigNum tmp;tmp.len=a.len;memset(tmp.num,0,sizeof(tmp.num));
for(int i=1;i<=tmp.len;i++)
{
tmp.num[i]+=a.num[i]*b;
if(tmp.num[i]>9)
{
tmp.num[i+1]+=tmp.num[i]/10;tmp.num[i]%=10;if(tmp.len==i)tmp.len++;
}
}
return tmp;
}
}a,b;
int main()
{
//freopen("in.txt","r",stdin);
scanf("%s",s+1);
a.len=strlen(s+1);
for(int i=1;i<=a.len;i++)a.num[a.len-i+1]=s[i]-'0';
scanf("%s",s+1);
b.len=strlen(s+1);
for(int i=1;i<=b.len;i++)b.num[b.len-i+1]=s[i]-'0';
int dou=0;
while(!(a.num[1]&1)&&!(b.num[1]&1))dou++,a=a/2,b=b/2;
while(!(a.num[1]&1))a=a/2;while(!(b.num[1]&1))b=b/2;
while(a.cmp(b)!=0)
{
if(a.cmp(b)==1)a=a-b;else b=b-a;
while(!(a.num[1]&1))a=a/2;while(!(b.num[1]&1))b=b/2;
}
while(dou--)a=a*2;
for(int i=a.len;i;i--)printf("%d",a.num[i]);
return 0;
}
總結
高精度的最大公約數