高精度模板
Posted tech-chen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高精度模板相关的知识,希望对你有一定的参考价值。
NOI 1:大整数加法
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
求两个不超过200位的非负整数的和。
- 输入
- 有两行,每行是一个不超过200位的非负整数,可能有多余的前导0。
- 输出
- 一行,即相加后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输出为0342。
- 样例输入
-
22222222222222222222 33333333333333333333
- 样例输出
-
55555555555555555555
- 来源
1 #define N 250 2 #include<iostream> 3 using namespace std; 4 #include<cstdio> 5 #include<cstring> 6 char a1[N],b1[N]; 7 int a[N],b[N],lena,lenb,lenc,c[N]; 8 int main() 9 { 10 scanf("%s%s",a1,b1); 11 lena=strlen(a1);lenb=strlen(b1); 12 for(int i=lena-1;i>=0;i--) 13 a[lena-i]=a1[i]-‘0‘; 14 for(int i=lenb-1;i>=0;i--) 15 b[lenb-i]=b1[i]-‘0‘; 16 lenc=1;int x=0; 17 while(lenc<=lena||lenc<=lenb) 18 { 19 c[lenc]=a[lenc]+b[lenc]+x; 20 x=c[lenc]/10; 21 c[lenc]%=10; 22 lenc++; 23 } 24 c[lenc]=x; 25 while(c[lenc]==0&&lenc>1) lenc--; 26 for(int i=lenc;i>=1;--i) 27 printf("%d",c[i]); 28 return 0; 29 }
11:大整数减法
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
求两个大的正整数相减的差。
- 输入
- 共2行,第1行是被减数a,第2行是减数b(a > b)。每个大整数不超过200位,不会有多余的前导零。
- 输出
- 一行,即所求的差。
- 样例输入
-
9999999999999999999999999999999999999 9999999999999
- 样例输出
- 9999999999999999999999990000000000000
1 #define N 250 2 #include<iostream> 3 using namespace std; 4 #include<cstdio> 5 #include<cstring> 6 #include<string> 7 int c[N],a[N],b[N],lena,lenb,lenc; 8 char a1[N],b1[N],t[N]; 9 int main() 10 { 11 scanf("%s%s",a1,b1); 12 lena=strlen(a1); 13 lenb=strlen(b1); 14 if(lena<lenb||(lena==lenb&&(strcmp(a1,b1)<0))) 15 { 16 strcpy(t,a1);strcpy(a1,b1);strcpy(b1,t); 17 swap(lena,lenb); 18 printf("-"); 19 } 20 21 for(int i=0;i<=lena-1;++i) 22 a[lena-i]=a1[i]-‘0‘; 23 for(int i=0;i<=lenb-1;++i) 24 b[lenb-i]=b1[i]-‘0‘; 25 lenc=1; 26 while(lenc<=lena||lenc<=lenb) 27 { 28 if(a[lenc]<b[lenc]) 29 { 30 a[lenc]+=10; 31 a[lenc+1]--; 32 } 33 c[lenc]=a[lenc]-b[lenc]; 34 lenc++; 35 } 36 while(c[lenc]==0&&lenc>1) lenc--; 37 for(int i=lenc;i>=1;--i) 38 printf("%d",c[i]); 39 return 0; 40 }
09:大整数乘法
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
求两个不超过200位的非负整数的积。
- 输入
- 有两行,每行是一个不超过200位的非负整数,没有多余的前导0。
- 输出
- 一行,即相乘后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输出为0342。
- 样例输入
-
12345678900 98765432100
- 样例输出
- 1219326311126352690000
1 #include<cstring> 2 #include<iostream> 3 using namespace std; 4 #include<cstdio> 5 const int N=211; 6 char a1[N],b1[N]; 7 int a[N],b[N],c[N*2],lena,lenb,lenc; 8 int main() 9 { 10 scanf("%s%s",a1,b1); 11 lena=strlen(a1);lenb=strlen(b1); 12 for(int i=0;i<=lena-1;++i) 13 a[lena-i]=a1[i]-‘0‘; 14 for(int i=0;i<=lenb-1;++i) 15 b[lenb-i]=b1[i]-‘0‘; 16 for(int i=1;i<=lena;++i) 17 { 18 int x=0; 19 for(int j=1;j<=lenb;++j) 20 { 21 c[i+j-1]+=x+a[i]*b[j]; 22 x=c[i+j-1]/10; 23 c[i+j-1]%=10; 24 } 25 c[i+lenb]=x; 26 } 27 lenc=lena+lenb; 28 while(c[lenc]==0&&lenc>1) lenc--; 29 for(int i=lenc;i>=1;--i) 30 printf("%d",c[i]); 31 printf("\n"); 32 return 0; 33 }
13:大整数的因子
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
已知正整数k满足2<=k<=9,现给出长度最大为30位的十进制非负整数c,求所有能整除c的k。
- 输入
- 一个非负整数c,c的位数<=30。
- 输出
- 若存在满足 c%k == 0 的k,从小到大输出所有这样的k,相邻两个数之间用单个空格隔开;若没有这样的k,则输出"none"。
- 样例输入
-
30
- 样例输出
- 2 3 5 6
1 /*用的非常暴力的做法,因为数的位数太小了,所以就暴力做,用a除b出一个序列,再用这个序列*b得到一个序列,和原序列,相同就是整除*/ 2 #include<iostream> 3 using namespace std; 4 #include<cstdio> 5 #include<cstring> 6 #define N 100 7 char a1[N]; 8 int a[N],lena,c[N],lenc; 9 int main() 10 { 11 scanf("%s",a1); 12 lena=strlen(a1); 13 for(int i=0;i<lena;++i) 14 a[i+1]=a1[i]-‘0‘; 15 bool biaozhi=false; 16 for(int b=2;b<=9;++b) 17 { 18 int x=0; 19 memset(c,0,sizeof(c)); 20 int duibi[N]={0}; 21 for(int i=1;i<=lena;++i) 22 { 23 c[i]=(10*x+a[i])/b; 24 x=(x*10+a[i])%b; 25 duibi[lena-i+1]=a[i]; 26 } 27 lenc=1; 28 while(c[lenc]==0&&lenc<lena) 29 lenc++; 30 int ans[N]={0}; 31 int lenans=0; 32 for(int i=lena;i>=lenc;--i) 33 ans[++lenans]=c[i]; 34 x=0; 35 for(int i=1;i<=lenans;++i) 36 { 37 ans[i]=ans[i]*b+x; 38 x=ans[i]/10; 39 ans[i]%=10; 40 } 41 if(ans[lenans+1]!=0) lenans++; 42 bool flag=true; 43 for(int i=1;i<=lenans;++i) 44 { 45 if(ans[i]!=duibi[i]) 46 { 47 flag=false;break; 48 } 49 } 50 if(flag) 51 { 52 printf("%d ",b); 53 biaozhi=true; 54 } 55 } 56 if(!biaozhi) printf("none\n"); 57 return 0; 58 }
47:大整数除法
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
求两个大的正整数相除的商。
- 输入
- 第1行是被除数,第2行是除数。每个数均不超过100位。
- 输出
- 一行,相应的商的整数部分
- 样例输入
-
2376 24
- 样例输出
- 99
1 #define N 201 2 #include<iostream> 3 using namespace std; 4 #include<cstdio> 5 #include<cstring> 6 void input(int *a) 7 { 8 string s; 9 cin>>s; 10 int lens=s.length(); 11 a[0]=lens; 12 for(int i=0;i<=lens-1;++i) 13 a[lens-i]=s[i]-‘0‘; 14 } 15 void numcpy(int *a,int *b,int det) 16 { 17 for(int i=1;i<=a[0];++i) 18 { 19 b[i+det-1]=a[i]; 20 } 21 b[0]=det+a[0]-1; 22 } 23 int cmp(int *a,int *b) 24 { 25 if(a[0]>b[0])return 1; 26 if(a[0]<b[0]) return -1; 27 for(int i=a[0];i>=1;--i) 28 { 29 if(a[i]>b[i]) return 1; 30 if(a[i]<b[i]) return -1; 31 } 32 return 0; 33 } 34 void jian(int *a,int *b) 35 { 36 int i=1; 37 int tem=cmp(a,b); 38 if(tem==0) 39 { 40 a[0]=0; 41 return; 42 } 43 while(i<=a[0]) 44 { 45 if(a[i]<b[i]) 46 { 47 a[i]+=10; 48 a[i+1]--; 49 } 50 a[i]-=b[i]; 51 i++; 52 } 53 while(a[0]>0&&a[a[0]]==0) a[0]--; 54 } 55 void cal(int *a,int *b,int *c) 56 { 57 c[0]=a[0]-b[0]+1; 58 int temp[N]; 59 for(int i=c[0];i>0;--i) 60 { 61 memset(temp,0,sizeof(temp)); 62 numcpy(b,temp,i); 63 while(cmp(a,temp)>=0) 64 { 65 c[i]++; 66 jian(a,temp); 67 } 68 } 69 while(c[0]>0&&c[c[0]]==0) c[0]--; 70 } 71 void print(int *a) 72 { 73 if(a[0]==0) 74 { 75 printf("0\n"); 76 return ; 77 } 78 for(int i=a[0];i>=1;--i) 79 printf("%d",a[i]); 80 printf("\n"); 81 } 82 int main() 83 { 84 int a[N]={0},b[N]={0},c[N]={0}; 85 input(a); 86 input(b); 87 cal(a,b,c); 88 print(c); 89 return 0; 90 }
48:实数加法
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
求两个实数相加的和。
题目中输入输出里出现的浮点数都有如下的形式:
P1P2...Pi.Q1Q2...Qj。对于整数部分,P1P2...Pi是一个非负整数且当整数部分不为0时,P1不等于0;对于小数部分,Qj不等于0。 - 输入
- 2行,每行是一个加数。每个加数的长度不超过100。
- 输出
- 一行,即相应的和。输出保证一定是一个小数部分不为0的实数。
- 样例输入
-
0.111111111111111111111111111111 0.111111111111111111111111111111
- 样例输出
- 0.222222222222222222222222222222
1 #include<iostream> 2 using namespace std; 3 #include<cstdio> 4 #include<cstring> 5 const int N=120; 6 string s; 7 int zz[N],ss[N],lenzz,lenss,z1[N],z2[N],s1[N],s2[N],lenz1,lenz2,lens1,lens2; 8 void input() 9 { 10 getline(cin,s,‘.‘); 11 lenz1=s.length(); 12 for(int i=0;i<=lenz1-1;++i) 13 z1[lenz1-i]=s[i]-‘0‘; 14 getline(cin,s); 15 lens1=s.length(); 16 for(int i=0;i<lens1;++i) 17 s1[i+1]=s[i]-‘0‘; 18 getline(cin,s,‘.‘); 19 lenz2=s.length(); 20 for(int i=0;i<=lenz2-1;++i) 21 z2[lenz2-i]=s[i]-‘0‘; 22 getline(cin,s); 23 lens2=s.length(); 24 for(int i=0;i<lens2;++i) 25 s2[i+1]=s[i]-‘0‘; 26 } 27 int main() 28 { 29 input(); 30 lenss=max(lens1,lens2); 31 for(int i=lenss;i>=1;--i) 32 { 33 ss[i]+=s1[i]+s2[i]; 34 ss[i-1]+=ss[i]/10; 35 ss[i]%=10; 36 } 37 while(ss[lenss]==0&&lenss>0) lenss--; 38 zz[1]+=ss[0]; 39 lenzz=max(lenz1,lenz2); 40 for(int i=1;i<=lenzz;++i) 41 { 42 zz[i]+=z1[i]+z2[i]; 43 zz[i+1]+=zz[i]/10; 44 zz[i]%=10; 45 } 46 if(zz[lenzz+1]) lenzz++; 47 for(int i=lenzz;i>=1;--i) 48 printf("%d",zz[i]); 49 printf("."); 50 for(int i=1;i<=lenss;++i) 51 printf("%d",ss[i]); 52 53 54 return 0; 55 }
以上是关于高精度模板的主要内容,如果未能解决你的问题,请参考以下文章