zoukankan      html  css  js  c++  java
  • 高精度计算:最大公约数【两个数字字符串】

    剪辑地址: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类型数字的最大公约数  【注意: C/C++里面数组名做参数传递进去的是数组的地址, 会发生值改变,如果原数组还有用,请先备份到另一个数组】

    #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
    ", gcd(aa, len, b));
        }
        return 0;
    }
    

     3.  HDU 4276 Cut the Cake (用上面的模板实现)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4762

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int m, n;
    
    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()
    {
        int a[201];
        int tg; scanf("%d", &tg);
        while(tg--)
        {
            scanf("%d %d", &m, &n);
            int head=200;
            memset(a, 0, sizeof(a));
            int jin, cur;
            a[head]=m;  //累乘计算 m^(n-1)
            for(int i=1; i<=n-2; i++){
                for(int j=200; j>=head; j--){
                    a[j]=a[j]*m;
                }
                jin=0;
                for(int j=200; j>=head; j--){
                    cur=(a[j]+jin)%10;
                    jin=(a[j]+jin)/10;
                    a[j]=cur;
                }
                if(jin>0){
                    head--; a[head]=jin;
                }
            }
            int b[201];
            for(int i=0; i<=200; i++)
                b[i]=a[i];
    
            int g=gcd( a+head, 200-head+1, n);
           // printf("gcd = %d
    ", g);
            printf("%d%c", n/g, '/');
            jin=0;
            for(int i=head; i<=200; i++){
                cur=(b[i]+jin*10)%g;
                b[i]=(b[i]+jin*10)/g;
                jin=cur;
            }
            while(b[head]==0 && head<=200) head++;
            for(int i=head; i<=200; i++)
                printf("%d", b[i]);
            printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    Windows 2008 R2 远程桌面服务(八)远程桌面服务器安全设置
    从硬盘上安装SQLServer2005的问题
    在 Windows server 2008 下计划任务无法正常执行bat批处理文件
    两部搞定windows server 2008 R2 中IE8的增强安全配置功能
    Microsoft SQL Server 2005 Service Pack 4 RTM
    学习地址
    Windows 2008 远程桌面如何设置两个用户共享一个会话
    Windows Server 2008 启用无线网卡
    远程桌面连接指定会话(Session)
    固定宽度弹性布局(以适应各种各辨率)
  • 原文地址:https://www.cnblogs.com/yspworld/p/4774062.html
Copyright © 2011-2022 走看看