高精度HighAccuracy

  1 /*HighAccuracy_oiwiki.cpp*/
  2 #include <cstdio>
  3 #include <cstring>
  4 
  5 static const int LEN = 10005;// 定义静态的长度变量LEN
  6 
  7 int a[LEN], b[LEN], c[LEN], d[LEN];// 定义高精度数组
  8 
  9 void clear(int a[]) {// 高精度数组清零操作
 10     for (int i = 0; i < LEN; ++i) a[i] = 0;
 11 }
 12 
 13 
 14 bool cmp(int a[], int b[])// 高精度比较函数
 15 {
 16     for (int i = LEN - 1; i >= 0; --i){
 17         if (a[i] > b[i]) return true;
 18         if (a[i] < b[i]) return false;
 19     }
 20     return true;
 21 }
 22 
 23 void read(int a[]) {// 输入高精度数
 24     static char s[LEN + 1];
 25     scanf("%s", s);
 26 
 27     clear(a);
 28 
 29     int len = strlen(s);
 30     for (int i = 0; i < len; ++i) a[len - i - 1] = s[i] - '0';//实现了倒序,即个十百千万0000···
 31 }
 32 
 33 void print(int a[]) {// 输出高精度数
 34     int i;
 35     for (i = LEN - 1; i >= 1; --i)//去掉后面的零,即 个十百千万0000··· 变成 个十百千万
 36         if (a[i] != 0) break;
 37     for (; i >= 0; --i) putchar(a[i] + '0');
 38     putchar('\n');
 39 }
 40 
 41 void add(int a[], int b[], int c[]) {// 高精度加法(高精度加高精度)
 42     clear(c);
 43 
 44     for (int i = 0; i < LEN - 1; ++i) {
 45         c[i] += a[i] + b[i];
 46         if (c[i] >= 10) {
 47             c[i + 1] += 1;
 48             c[i] -= 10;
 49         }
 50     }
 51 }
 52 
 53 void sub(int a[], int b[], int c[]) {// 高精度减法(高精度减高精度)
 54     clear(c);
 55 
 56     for (int i = 0; i < LEN - 1; ++i) {
 57         c[i] += a[i] - b[i];
 58         if (c[i] < 0) {
 59             c[i + 1] -= 1;
 60             c[i] += 10;
 61         }
 62     }
 63 }
 64 
 65 void mul(int a[], int b[], int c[]) {// 高精度乘法(高精度乘以高精度)
 66     clear(c);
 67 
 68     for (int i = 0; i < LEN - 1; ++i) {
 69         for (int j = 0; j <= i; ++j) c[i] += a[j] * b[i - j];
 70 
 71         if (c[i] >= 10) {
 72             c[i + 1] += c[i] / 10;
 73             c[i] %= 10;
 74         }
 75     }
 76 }
 77 
 78 inline bool greater_eq(int a[], int b[], int last_dg, int len) {// 判断大小数组(具体原理请参照OIwiki)
 79   if (a[last_dg + len] != 0) return true;
 80   for (int i = len - 1; i >= 0; --i) {
 81     if (a[last_dg + i] > b[i]) return true;
 82     if (a[last_dg + i] < b[i]) return false;
 83   }
 84   return true;
 85 }
 86 
 87 void div(int a[], int b[], int c[], int d[]) {// 高精度除法(高精度除以高精度)
 88   clear(c);
 89   clear(d);
 90 
 91   int la, lb;
 92   for (la = LEN - 1; la > 0; --la)
 93     if (a[la - 1] != 0) break;
 94   for (lb = LEN - 1; lb > 0; --lb)
 95     if (b[lb - 1] != 0) break;
 96   if (lb == 0) {
 97     puts("> <");
 98     return;
 99   }
100 
101   for (int i = 0; i < la; ++i) d[i] = a[i];
102   for (int i = la - lb; i >= 0; --i) {
103     while (greater_eq(d, b, i, lb)) {
104       for (int j = 0; j < lb; ++j) {
105         d[i + j] -= b[j];
106         if (d[i + j] < 0) {
107           d[i + j + 1] -= 1;
108           d[i + j] += 10;
109         }
110       }
111       c[i] += 1;
112     }
113   }
114 }
115 
116 int main() {
117     freopen("luogu_in.txt","r",stdin);  // 文件输入  
118     freopen("luogu_out.txt","w",stdout);// 文件输出  
119     read(a);
120 
121     char op[4];
122     scanf("%s", op);
123 
124     read(b);
125 
126     switch (op[0]) {
127         case '+':
128             add(a, b, c);
129             print(c);
130             break;
131         case '-':
132             if(cmp(a, b)) sub(a, b, c);
133             else{
134                printf("-");
135               sub(b, a, c);
136             }
137             print(c);
138             break;
139         case '*':
140             mul(a, b, c);
141             print(c);
142             break;
143         case '/':
144             div(a, b, c, d);
145             print(c);
146             print(d);
147             break;
148         default:
149             puts("> <");
150     }
151 
152     return 0;
153 }

  1 /*HighAccuracy_acwing.cpp*/
  2 #include<bits/stdc++.h>
  3 using namespace std;
  4 
  5 
  6 bool sub_plus(vector<int> &a, vector<int> &b){//0表示负数,1表示正数
  7     if(a.size()<b.size()) return 0;
  8     if(a.size()==b.size()){
  9         for(int i = 0; i<a.size(); i++){
 10             if(a[i]<b[i]){
 11                 return 0;
 12             }
 13         }
 14     }
 15     return 1;
 16 }
 17 
 18 vector<int> add(vector<int> &A, vector<int> &B){  //正序输入两个vector类型的“数”
 19     if (A.size() < B.size()) return add(B, A);  //使得A数组是最大的
 20     //如果未反转,在if下面加reverse,不能在if上面加reverse,否者二次反转,等于没有反转
 21 
 22     reverse(A.begin(),A.end());  //反转数组,变成个十百千万···
 23     reverse(B.begin(),B.end());
 24     vector<int> c;  //初始化答案数组
 25     int t = 0;
 26     for (int i = 0; i < A.size(); i ++ ){
 27         t += A[i];
 28         if (i < B.size()) t += B[i];  //如果B还有数字
 29         c.push_back(t % 10);
 30         t /= 10;
 31     }
 32     if (t) c.push_back(t);//最后一次加法可能还有进位的数,把最高位补上
 33     while (c.size() > 1 && c.back() == 0) c.pop_back();//处理前导零
 34     reverse(c.begin(), c.end());
 35     return c;
 36 }
 37 
 38 // C = A - B, 满足A >= B, A >= 0, B >= 0
 39 vector<int> sub(vector<int> &A, vector<int> &B){
 40     reverse(A.begin(),A.end());  //反转数组,变成个十百千万···
 41     reverse(B.begin(),B.end());
 42     vector<int> C;
 43     for (int i = 0, t = 0; i < A.size(); i++ ){
 44         t = A[i] - t;
 45         if (i < B.size()) t -= B[i];
 46         C.push_back((t + 10) % 10);//无论如何,先向高位借1
 47         if (t < 0) t = 1;//t是负数,说明是真的借1了
 48         else t = 0;//t是非负数,说明不用借1
 49     }
 50     while (C.size() > 1 && C.back() == 0) C.pop_back();
 51     reverse(C.begin(), C.end());
 52     return C;
 53 }
 54 
 55 //不清楚c数组开多大
 56 vector<int> multwo(vector<int> &a, vector<int> &b){
 57     if(a.size()<b.size()) return multwo(b,a);
 58     vector<int> c(1000001,0);  //初始化答案数组(不知道开多大)
 59     reverse(a.begin(), a.end());  //反转数组,变成个十百千万···
 60     reverse(b.begin(), b.end());
 61     int t = 0;
 62     for(int i = 0; i<b.size(); i++){  //b数组数少,是外循环
 63         for(int j = 0; j<a.size() || t; j++){  //a数组数多,是内循环
 64             if(j<a.size()) t += a[j]*b[i];
 65             c[j+i] += t % 10;
 66             t /= 10;
 67         }
 68     }
 69     //处理c数组的进位
 70     for(int i = 0; i<a.size()*b.size(); i++){  //无论数字如何大,数位也不会大于两个乘数的和
 71         if(c[i]>9){
 72             c[i+1]+=c[i]/10;
 73             c[i]%=10;
 74         }
 75     }
 76     while (c.size() > 1 && c.back() == 0) c.pop_back();  //末尾可能是0,都要去掉(我感觉是多余的,不可能有这种情况)(难道是处理b==0?)
 77     reverse(c.begin(), c.end());
 78     return c;
 79 }
 80 
 81 /*除法*/
 82 // A / b = C ... r, A >= 0, b > 0
 83 vector<int> div(vector<int> &A, int b, int &r){
 84     reverse(A.begin(), A.end());
 85     vector<int> C;
 86     r = 0;
 87     for (int i = A.size() - 1; i >= 0; i -- ){  //从右向左
 88         r = r * 10 + A[i];  //高位除不尽的数,留给低位
 89         C.push_back(r / b);
 90         r %= b;
 91     }//高位在左,低位在右
 92     reverse(C.begin(), C.end());//低位在左,高位在右
 93     while (C.size() > 1 && C.back() == 0) C.pop_back();
 94     reverse(C.begin(), C.end());//高位在左,低位在右
 95     return C;
 96 }
 97 
 98 int main(){
 99     string in; getline(cin,in);
100     vector<int> a;
101     vector<int> b;
102     vector<int> c;
103     char f;
104     int i;
105 
106     for(i = 0; i<in.size(); i++){
107         if(in[i]!=' ') a.push_back(in[i]-'0');
108         else break;
109     }
110 
111     i++;
112     f = in[i];
113     i+=2;
114 
115     for(i; i<in.size(); i++) b.push_back(in[i]-'0');
116 
117     switch (f) {
118         case '+':
119             c = add(a,b);
120             break;
121         case '-':
122             //增加负号
123             if(!sub_plus(a,b)){
124                 printf("-");
125                 c = sub(b,a);
126             }
127             else c = sub(a,b);
128             break;
129         case '*':
130             c = multwo(a,b);
131             break;
132         case '/':
133             int bb = b[0]; int d;
134             c = div(a,bb,d);
135             break;
136         // default:
137         //     puts("> <");
138     }
139     for(int i = 0; i<c.size(); i++) printf("%d", c[i]);
140 
141     return 0;
142 }

 

posted @ 2022-10-29 15:54  唔知叫咩emm  阅读(168)  评论(0编辑  收藏  举报