洛谷P2152 [SDOI2009] SuperGCD

[SDOI2009] SuperGCD

题目描述

Sheng bill 有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的最大公约数!因此他经常和别人比赛计算最大公约数。有一天Sheng bill很嚣张地找到了你,并要求和你比赛,但是输给 Sheng bill 岂不是很丢脸!所以你决定写一个程序来教训他。

输入格式

共两行,第一行一个整数 a a a,第二行一个整数 b b b

输出格式

一行,表示 a a a b b b 的最大公约数。

样例 #1

样例输入 #1

12
54

样例输出 #1

6

提示

数据规模与约定
  • 对于 20 % 20\% 20% 的数据,有 0 < a , b ≤ 1 0 18 0<a,b\le 10^{18} 0<a,b1018
  • 对于 100 % 100\% 100% 的数据,有 0 < a , b ≤ 1 0 10000 0<a,b\le 10^{10000} 0<a,b1010000

前置芝士

**

更相减损术

若a偶&&b偶			将a/=2,b/=2;
若a偶&&b奇			a/=2;
若a奇&&b偶			b/=2

**

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
char s[N];
struct node{
	int len,num[N];
	friend	node  operator /(const node&a,const int &b)
	{
		node 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 node&b)const
	{
		if(len<b.len)	return -1;
		if(len>b.len)	return 1;
		for(int i=len;i;i--)
		{
			if(b.num[i]>num[i])	return -1;
			if(b.num[i]<num[i])	return 1;
		}
		return 0;	
	}
	friend node operator -(node&a,const node&b)
	{
		node 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 node operator *(node&a,const int&b)
	{
		node tmp;int num=0;
		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]>=10)
			{
				tmp.num[i+1]+=tmp.num[i]/10;
				tmp.num[i]%=10;
				if(tmp.len==i)
					tmp.len++; 
			} 	
		}
		return tmp;  
	}
}a,b;
int main()
{
	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]-48; 
	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]-48; 
	int even=0;
	while(!(a.num[1]&1)&&!(b.num[1]&1))	even++,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(even--)
		a=a*2;
	for(int i=a.len;i>=1;i--)
		cout<<a.num[i];	
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值