您的位置:首页 > 其它

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

2016-08-11 21:20 399 查看
本文总结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=alen-1;i>=0;i--)

{
for (j=blen-1;j>=0;j--)

sum=sum+res[i+blen-j-1][j];

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

}

for (i=blen-2;i>=0;i--)

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

sum=sum+res[i-j][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=k-1;i>=0;i--) s[i]=result[k-1-i];

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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: