清北学堂2019NOIP提高储备营DAY4

今天只有一上午,讲的东西不多,这里就整理一下高精的东西,数论部分请见my blog

高精度:

先讲一讲进制问题:十进制的二进制表示:以10为例,  

    10的二进制表示为1010

    10的三进制表示为101

将一个十进制的x转为k进制

    要求把十进制的55转为三进制的表示

    短除法如下:

  3|55……1

  3|18……0

  3|6……0

  3|2……2

扫描二维码关注公众号,回复: 6082384 查看本文章

    0

  将所有余数从下向上写出,55的三进制表示为2001

将一个k进制的数转成十进制的数

    根据定义,k进制的xnxn-1xn-2……x0可以转为x·k^n+x·k^n-1+……+x·k^0

二进制、八进制、十进制、十六进制

  • 计算机中最常用的进制
  • 在C++中写一个二进制,只需要在前面加上一个前导0
  • 十六进制:用字母对应10到15(A~F),所以0x3f3f3f3f≈1.1*10^9

高精度的目的:用C++自带的类型,十进制一旦超过20位,就无法进行运算,高精度运算的目的就是通过模拟竖式加减乘除法

高精度步骤:

    (1)个位对齐

    (2)逐位相加

    (3)注意进位

高精度的存储:

    用数组来存每一位

    以19260817为例,如果按照顺序存储,就会存成19260817。这样就不能满足个位对齐的步骤,那么我们就要反着存,即71806291,这样在做加法时个位一定是对齐的

高精度的代码(钟神的写法,只需要将int a,b转换成gaojing a,b)

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 using namespace std;
 6 
 7 struct gaojing
 8 {
 9     int z[10010];//用来存这个数的数组,0表示个位,以此类推 
10     int l;//表示这个数是一个l位的数 
11     gaojing()
12     {
13         l=1;
14         memset(z,0,sizeof(z));
15     }//构造函数,每次声明一个高精类,函数都会运行一次 
16     
17     friend istream& operator>>(istream &cin,gaojing &a)//意思是用cin这个读入函数读入a,friend叫做有缘函数 
18     {
19         static/*在函数中开数组的局部变量,一定要加static*/ char s[10010];
20         cin>>s;
21         int l=strlen(s);
22         for(int i=0;i<=l;++i)
23         {
24             a.z[i]=s[l-i-1]-'0';
25         }
26         a.l=l;
27         return cin;//第17行和第27行当做模板记就行了 
28     } 
29     
30     friend ostream&operator<<(ostream &cout,const gaojing &a)
31     {
32         for(int i=a.l-1;i>=0;i--)
33         {
34             cout<<a.z[i];
35         }
36         return cout;
37     }
38 };
39 //写一下需要的运算符:+ - * / % < <= > >= == != cin>> cout<<
40 //这里只对 
41 //运用重载运算符
42 gaojing operator+(const gaojing &a,const gaojing &b)//定义的时高精度之间的加法,不影响正常的加法,返回类型也应该是一个高精度的数 
43 //需要注意,gaojing a时,系统会对a进行备份,只在这个函数中运用,gaojing &a时,系统会直接将a的值传过来
44 //a和b是一个高精度的东西,如果不用取址符号,将会在每一次运行函数时都拷贝一个很大很大的数组,所以在a,b前边加上&
45 //但是如果手抖将a和b的值改动,应该加一个const(来自钟神的关爱),如果要将这个函数喂给STL,const是必不可少的 
46 { 
47     gaojing c;
48     int l=max(a.l,b.l);
49     for(int i=0;i<l;++i)
50     {
51         c.z[i]=a.z[i]+b.z[i];
52         c.z[i+1]+=c.z[i]/10;
53         c.z[i]=c.z[i]%10;//模拟的是进位的情况 
54     }
55     if(c.z[l]!=0) l++;
56     c.l=l;//检查是否有进位 
57     return c;
58 }
59 
60 gaojing operator*(const gaojing &a,const gaojing &b)
61 {
62     gaojing c;
63     for(int i=0;i<a.l;++i)
64         for(int j=0;j<=b.l;++j)
65             c.z[i+j]=a.z[i]*b.z[j];
66     c.l=a.l+b.l;
67     for(int i=0;i<c.l;++i)
68     {
69         c.z[i+1]+=c.z[i]/10;
70         c.z[i]=c.z[i]%10;
71     }
72     while(c.l>0&&c.z[c.l]==0)//找第一个不等于0的c.l,这时的l为c.z[i]的长度 
73         c.l--;
74     if(c.l==0) c.l++; 
75     return c;
76 }
77 
78 int main()
79 { 
80     gaojing x,y;
81     cin>>x>>y;
82     cout<<x+y<<endl<<x*y<<endl;
83 }

猜你喜欢

转载自www.cnblogs.com/juruohqk/p/10799305.html