码迷,mamicode.com
首页 > 其他好文 > 详细

计算两个超大数字的 最大公约数【两个数字字符串】

时间:2015-08-31 21:21:08      阅读:332      评论:0      收藏:0      [点我收藏+]

标签:

剪辑地址:http://hzwer.com/3023.html

 

计算两个超级大数的最大公约数:

样例:

111111111111111111111

22222222222222222222222222222

输出:

我也不知道~~~

 

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#define inf 1000000000
using namespace std;
char ch1[10005],ch2[10005];
int la,lb,cnt;
struct data{int a[1205],l;}a,b;
bool com()
{
	if(a.l<b.l)return 0;
	if(a.l>b.l)return 1;
	for(int i=a.l;i>0;--i)
	    if(a.a[i]>b.a[i])return 1;
	    else if(a.a[i]<b.a[i])return 0;
	return 1;
}
void print(data a)
{
    while(a.a[a.l]==0)a.l--;
	for(int i=a.l;i>0;--i)
	    if(i==a.l)printf("%d",a.a[i]);
	    else printf("%09d",a.a[i]);
}
inline data sub(data a,data b)
{
	int k;
    data c;
	for(int i=1;i<=1200;++i)
	{
	   if(i<=b.l)c.a[i]=a.a[i]-b.a[i];
	   else if(i<=a.l)c.a[i]=a.a[i];
	   else c.a[i]=0;
	   if(c.a[i]<0)
	   {
	      c.a[i]+=inf;
	      a.a[i+1]--;
	   }
    }
    c.l=a.l;
    while(c.a[c.l]==0&&c.l)c.l--;
    return c;
}
void diva()
{
	for(int i=1;i<=a.l;i++)
	{
	    if(a.a[i]&1)a.a[i-1]+=inf/2;
	    a.a[i]>>=1;
	}
	if(!a.a[a.l])a.l--;
}
void divb()
{
    for(int i=1;i<=b.l;i++)
	{
	    if(b.a[i]&1)b.a[i-1]+=inf/2;
	    b.a[i]>>=1;
	}
	if(!b.a[b.l])b.l--;
}
void mul()
{
	for(int i=a.l;i>0;i--)
	{
	   a.a[i]<<=1;
	   a.a[i+1]+=a.a[i]/inf;
	   a.a[i]%=inf;
    }
    while(a.a[a.l]>0)a.l++;
    for(int i=b.l;i>0;i--)
	{
	   b.a[i]<<=1;
	   b.a[i+1]+=b.a[i]/inf;
	   b.a[i]%=inf;
    }
    while(b.a[b.l]>0)b.l++;
}
int main()
{
	scanf("%s%s",ch1+1,ch2+1);
	la=strlen(ch1+1);lb=strlen(ch2+1);
	if(la%9)a.l=la/9+1;
	else a.l=la/9;
	if(lb%9)b.l=lb/9+1;
	else b.l=lb/9;
	for(int i=1;i<=a.l;++i)
	{
		int k1=max(1,la-i*9+1),k2=la-(i-1)*9;
		for(int j=k1;j<=k2;++j)
		    a.a[i]=a.a[i]*10+ch1[j]-‘0‘;
	}
	for(int i=1;i<=b.l;++i)
	{
		int k1=max(1,lb-i*9+1),k2=lb-(i-1)*9;
		for(int j=k1;j<=k2;++j)
		    b.a[i]=b.a[i]*10+ch2[j]-‘0‘;
	}
	while(1)
    {
    	if((a.a[1]%2==0)&&(b.a[1]%2==0)){diva();divb();cnt++;}
    	else if((a.a[1]%2==0))diva();
    	else if((b.a[1]%2==0))divb();
	    if(com()){a=sub(a,b);if(!a.l){while(cnt--)mul();print(b);break;}}
	    else {b=sub(b,a);if(!b.l){while(cnt--)mul();print(a);break;}}
    }
	return 0;
}

 

2. 计算一个大数与int类型数字的最大公约数

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//计算一个大数与一个int型整数的最大公约数模板

int gcd2(int a, int b)
{
    return b==0?a:gcd2(b, a%b);
}
int gcd(int *a, int len, int b){
    int yu;//保存大数对b取余后的余数
    int i, jin=0;//数组存储在0--(len-1)
    int cur;
    for(i=0; i<len; i++){
        cur=(a[i]+jin*10)%b;
        jin=cur;
    }
    if(jin==0){//说明可以整除 则最大公约数是b
        return b;
        //也可以计算输出商
    }
    else{//再计算(大数a%b)与b的最大公约数
        return gcd2(jin, b);
    }
}

int main()
{
    char a[1001]; int b;
    int aa[1001];

    while(scanf("%s %d", a, &b)!=EOF)
    {
        //将字符串转换成数字串
        int len=strlen(a);
        for(int i=0; i<len; i++){
            aa[i]=a[i]-48;
        }
        printf("%d\n", gcd(aa, len, b));
    }
    return 0;
}

 

计算两个超大数字的 最大公约数【两个数字字符串】

标签:

原文地址:http://www.cnblogs.com/yspworld/p/4774062.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!