ACM 大数问题的知识点与算法

本文总结ACM大数问题的概念与常用算法

大数是指计算的数值非常大或者对运算的精度要求非常高,用已知的数据类型无法表示的数值。

1、整型

Short : 16位整数,占两个字节,-2^15——2^15-1   (-32768 —— 32768)

Unsigned short : 占2个字节, 0——2^16   (0——65535)

Int : 32位整数,占4个字节,-2^31——2^31-1 

Unsigned int : 占四个字节,0 —— 2^31-1

Long == int(由于现在使用的都是32位系统)

2、VC的64位整数

__int64: 占8字节,-2^63 —— 2^63-1

Unsigned __int64: 占8字节,0——2^64-1

3、G++的64位整数

Long long == __int64

Unsigned long long == unsigned __int64

4、实数

Float:占四个字节,7位有效数字

Double: 占8个字节,15位有效数字

浮点型的问题都是追求精度的,在一般情况下我们应当选择使用double,而很少用float.

5、基本的思想是:用数组存放和表示大整数。一个数组元素存放大整数中的一位

大数运算的方法

6、用数组来模拟大数的运算(加、减、乘、除、任意精度计算)

1.大数加法

#include<iostream>

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

using namespace std;

 

void add(char *a,char *b,char *back)

{int i,j,k,up,x,y,z,l;

char *c;

if(strlen(a)>strlen(b))  l=strlen(a)+2;//可能有进位

else l=strlen(b)+2;

c=(char *) malloc(l*sizeof(char));

i=strlen(a)-1;j=strlen(b)-1;k=0;   up=0;

 

while(i>=0||j>=0)

{if(i<0) x=’0′;else x=a[i];

if(j<0) y=’0′;else y=b[j];

z=x-‘0’+y-‘0’;//在相同的位置的数相加

if(up) z+=1;//up表示进位

if(z>9) {up=1;z%=10;} else up=0;

c[k++]=z+’0′;

i–;j–;

}

 

if(up) c[k++]=’1′;

i=0;c[k]=’\0′;

for(k-=1;k>=0;k–)back[i++]=c[k];//保存结果在back[]数组中

back[i]=’\0′;

}

 

int main()

{int i;

char a[201],b[201],c[210];

cin>>a>>b;add(a,b,c);

for(i=0;c[i]!=’\0′;i++)

printf(“%c”,c[i]);

printf(“\n”);

return 0;

}

 

2.大数乘法

#include <stdio.h> 

#include <string.h> 

 

#define N 100 

#define M 1000 

 

void mult(char a[],char b[],char s[]) 

{   int i,j,k=0,alen,blen,sum=0,res[M][N]={0},flag=0; 

        char result[N*N]; 

        alen=strlen(a); blen=strlen(b);  

        for (i=0;i<alen;i++) 

                for (j=0;j<blen;j++)   

                        res[i][j]=(a[i]-‘0’)*(b[j]-‘0’); 

        for (i=alen1;i>=0;i–) 

        {       for (j=blen1;j>=0;j–)   

                        sum=sum+res[i+blenj1][j]; 

                result[k]=sum%10; k=k+1; sum=sum/10; 

        } 

        for (i=blen2;i>=0;i–) 

        {       for (j=0;j<=i;j++)  

                        sum=sum+res[ij][j]; 

                result[k]=sum%10; k=k+1;  sum=sum/10; 

        } 

        if (sum!=0) {  result[k]=sum;  k=k+1;} 

        for (i=0;i<k;i++) result[i]+=‘0’; 

        for (i=k1;i>=0;i–) s[i]=result[k1i]; 

        s[k]=‘\0’; 

        while(1) 

        {   if (strlen(s)!=strlen(a)&&s[0]==‘0’) strcpy(s,s+1); 

                else    break; 

        } 

}  

int main() 

{ char a[20],b[1000],c[1000]; 

        int n,i;          

        scanf(“%s%d”,a,&n); 

        strcpy(b,a);          

        for (i=2;i<=n; i++) 

        { mult(b,a,c); strcpy(b,c);  }

printf(“%s\n”,c);

return 0;

}

 

3.大数减法

#include<iostream>

#include<stdio.h>

#include<string.h>

using namespace std;

 

void sub(char s1[],char s2[],char t[])

{

int i,l2,l1,k;

l2=strlen(s2);l1=strlen(s1);

t[l1]=’\0′;l1–;

for (i=l2-1;i>=0;i–,l1–)

{if (s1[l1]-s2[i]>=0)t[l1]=s1[l1]-s2[i]+’0′;

else

{t[l1]=10+s1[l1]-s2[i]+’0′;

s1[l1-1]=s1[l1-1]-1;

}

}

k=l1;

while(s1[k]<0) {s1[k]+=10;s1[k-1]-=1;k–;}

while(l1>=0) {t[l1]=s1[l1];l1–;}

loop:

if (t[0]==’0′)

{l1=strlen(s1);

for (i=0;i<l1-1;i++) t[i]=t[i+1];t[l1-1]=’\0′;

goto loop;

}

if (strlen(t)==0)  {t[0]=’0′;t[1]=’\0′;}

}

 

int main()

{

int n;

char a[100],b[100],c[100];

cin>>n;

while(n–)

{cin>>a>>b;

sub(a,b,c);

cout<<c<<endl;

}

return 0;

}

    原文作者:大整数乘法问题
    原文地址: https://blog.csdn.net/LiuJiuXiaoShiTou/article/details/52186641
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞