Description
Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比赛计算GCD。有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但是输给Sheng bill岂不是很丢脸!所以你决定写一个程序来教训他。
Input
共两行: 第一行:一个数A。 第二行:一个数B。
Output
一行,表示A和B的最大公约数。
Sample Input
12
54
54
Sample Output
6
HINT
对于20%的数据,0 < A , B ≤ 10 ^ 18。
对于100%的数据,0 < A , B ≤ 10 ^ 10000。
题解
高精度的模板题,有高精减高精,高精乘单精,高精除单精。
对于更相减损术,有一点可以优化,就是若两者都能整除2,就记录一下,然后除完继续做,如果只有一个能整除2,就直接除掉即可。
最后,我的高精度模板还是很难看啊……
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<algorithm>
#define M 100000000
using namespace std;
char A[10010],B[10010];
struct shu
{
int l,s[1300];
void operator -= (shu x)
{int i;
for(i=1;i<=l;i++)
{s[i]-=x.s[i];
if(s[i]<0) {s[i]+=M; s[i+1]--;}
}
while(s[l]==0&&l>1) l--;
}
}
a,b,c;
int cnt2=0;
void init()
{
scanf("%s%s",A+1,B+1);
int i,t,j;
char c;
i=strlen(A+1);
while(i>0)
{t=0;
for(j=max(i-7,1);j<=i;j++) t=t*10+(A[j]-'0');
a.s[++a.l]=t; i-=8;
}
i=strlen(B+1);
while(i>0)
{t=0;
for(j=max(i-7,1);j<=i;j++) t=t*10+(B[j]-'0');
b.s[++b.l]=t; i-=8;
}
}
shu operator /(shu x,int y)
{
shu ans;
memset(ans.s,0,sizeof(ans.s));
int i;
for(i=x.l;i>0;i--)
{if(i>1) x.s[i-1]+=(x.s[i]%y)*M;
ans.s[i]=x.s[i]/y;
}
i=x.l;
while(i>1&&ans.s[i]==0) i--;
ans.l=i;
return ans;
}
int cmp(shu x,shu y)
{
if(x.l>y.l) return 1;
else if(x.l<y.l) return 0;
else
{int i;
for(i=x.l;i>0;i--)
{if(x.s[i]<y.s[i]) return 0;
else if(x.s[i]>y.s[i]) return 1;
}
}
return 1;
}
bool check(shu x)
{
if(x.s[1]==0&&x.l==1) return false;
return true;
}
void gcd(shu x,shu y)
{
while(check(x)&&check(y))
{if((x.s[1]%2==0)&&(y.s[1]%2==0))
{cnt2++; x=x/2; y=y/2;
}
else if(x.s[1]%2==0) x=x/2;
else if(y.s[1]%2==0) y=y/2;
else
{if(cmp(x,y)) x-=y;
else y-=x;
}
}
if(!check(x)) c=y;
else c=x;
}
shu operator *(shu x,int y)
{
shu ans;
memset(ans.s,0,sizeof(ans.s));
int i;
for(i=1;i<=x.l;i++) ans.s[i]=x.s[i]*y;
for(i=1;i<=x.l;i++)
{if(ans.s[i]>=M)
{ans.s[i+1]+=ans.s[i]/M;
ans.s[i]%=M;
}
}
i=x.l+1;
while(ans.s[i]>0)
{if(ans.s[i]>=M)
{ans.s[i+1]+=ans.s[i]/M;
ans.s[i]%=M;
}
i++;
}
ans.l=i-1;
return ans;
}
int main()
{
init();
gcd(a,b);
while(cnt2--) c=c*2;
printf("%d",c.s[c.l]);
for(int i=c.l-1;i>0;i--) printf("%08d",c.s[i]);
printf("\n");
return 0;
}