高精度模板

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 }

 



以上是关于高精度模板的主要内容,如果未能解决你的问题,请参考以下文章

NOI中“大整数加法”问题不能AC的解决建议

高精度运算

高精度计算:大整数加法

noi1_13_48[实数加法]

高精度加法

算法竞赛模板(数论)