题解 P1797 【克鲁斯的加减法_NOI导刊2010提高(05)】

· · 题解

这可能是最长的一片题解,但思路应该是很清晰的 首先这道题可以模拟或者重载 因为重载看着太丑了,我选择了模拟大法 首先思路如下 考虑这串字符可能有几种形式

  1. +++++数字
  2. +(数字)数字
  3. +数字
  4. 只有数字
  5. ----数字
  6. -(数字)数字
  7. -数字

因为要考虑正负号所以不能直接加或减 正加正直接加;正加负变成正减正;负加负,改为正加正,标记不变;负减负变成正减负; 但如果每次操作都考虑正负号会非常的繁琐 所以我们用两个数组 一个记录加的操作的总和 一个记录减的操作的总和 这样只需要在输出答案的时候判断一下正负号即可 另外还有读入时数是从高位开始存的 所以每次读入后我们都翻转一下数组 让最低位在数组开始的位置 这样进位的操作会很好实现 还要处理好两个答案数组的长度

接下来就放出我的巨长的代码 ————————>


# include <iostream>
# include <string>
# include <cstring>
# include <algorithm>
# include <cstdio>
# define ll long long
using namespace std;

char s[1000100];
int len,tot,ans_l = 1,cnt,ans_r = 1,ans_len;
int st[1000100],a[1000100],ans1[1000100],que[1000000],mu[1000100],ans2[1000100],ans[1000100];

void change(){
    for (int i = 1 ; i <= tot; i ++) a[i] = st[i];
    for (int  i = 1 ; i <= tot ; i++) st[i] = a[tot-i+1];
}

void tchange(){
    for (int i = 1 ; i <= cnt ; i++) a[i] = que[i];
    for (int i= 1 ; i <= cnt ; i++) que[i] = a[cnt-i+1];
}

void mul(int sum){
    int jin = 0;
    for (int i = 1 ; i <= tot ;i++){
        st[i] = st[i] * sum + jin;
        jin = st[i] / 10;
        st[i] %= 10;
    }
    if(jin){tot++; st[tot] += jin;}
}

void add(){
    int r = max(ans_l,tot); int jin = 0;
    for (int i = 1 ; i <= r ; i++){
        ans1[i] = ans1[i] + st[i] + jin;
        jin = ans1[i] / 10;
        ans1[i] %= 10;
    }
    ans_l = r;
    while(ans1[ans_l] == 0) ans_l--;
}

void Add(){
    int r = max(ans_r,tot); int jin = 0;
    for (int i = 1 ; i <= r ; i++){
        ans2[i] = ans2[i] + st[i] + jin;
        jin = ans2[i] / 10;
        ans2[i] %= 10;
    }
    ans_r = r;
    while(ans2[ans_r] == 0) ans_r--;
}

void Mmul(){
    memset(mu,0,sizeof(mu));
    int jin = 0; int lenn = 1;
    for (int i = 1 ; i <= tot ; i++){
        for (int j = 1 ; j <= cnt ; j++){
            mu[i+j-1] += st[i] * que[j];
            mu[i+j] += mu[i+j-1] / 10;
            mu[i+j-1] %= 10;
        }
    }
    lenn = tot+cnt;
    while(mu[lenn] == 0) lenn--;    
    memset(st,0,sizeof(st));
    for (int i = 1 ; i <= lenn ; i++) st[i] = mu[i];
    tot = lenn;
}

void jian1(){
    int r = max(ans_l,ans_r); int jin = 0;  
    for (int i = 1 ; i <= r ; i++){
        ans[i] = ans2[i] - ans1[i];
        if(ans[i] < 0) ans[i] += 10,ans2[i+1] -= 1;
    }   
    while(ans[r] == 0) r--;
    ans_len = r;
}

void jian2(){
    int r = max(ans_l,ans_r); int jin = 0;
    for (int i = 1 ; i <= r ; i++){
        ans[i] = ans1[i] - ans2[i];
        if(ans[i] < 0) ans[i] += 10, ans1[i+1] -= 1;
    }
    while(ans[r] == 0) r--;
    ans_len = r;
}

bool check(){
    if(ans_l < ans_r) return 1;
    if(ans_l > ans_r) return 0;
    if(ans_l == ans_r){
        for (int i = ans_l ; i >= 1 ; i--){
            if(ans1[i] < ans2[i]) return 1;
            if(ans1[i] > ans2[i]) return 0;
            if(ans1[i] == ans2[i]) continue;
        }
    }
    return 0;
}

int main(){
    cin >> s+1;
    len = strlen(s+1) ;
    for (int i = 1 ; i <= len ; i++){
        if(s[i] == '+' && s[i+1] == '+'){
            memset(st,0,sizeof(st));
            int x = i; cnt = 0; tot = 0;
            while(s[x] <'0' || s[x] >'9') x++,cnt++;
            while(s[x] >= '0' && s[x] <= '9') st[++tot] = s[x++] - '0';
            change(); mul(cnt); add();
            i = x - 1; continue;
        }
        if(s[i] == '+' && s[i+1] == '('){
            memset(st,0,sizeof(st)); memset(que,0,sizeof(que));
            int x = i + 2; tot = 0; cnt = 0;
            while(s[x] >='0' && s[x] <='9') que[++cnt] = s[x++] - '0'; 
            tchange();
            if(s[x] == ')'){
                x ++;
                while(s[x] >='0' && s[x] <='9') st[++tot] = s[x++] - '0';
                 change();  
            }           
            Mmul(); add();
            i = x - 1; 
            continue;       }
        if(s[i] == '+'){
            if(s[i+1] >= '0' && s[i+1] <= '9'){
                memset(st,0,sizeof(st));
                int x = i + 1; tot = 0;
                while(s[x] >= '0' && s[x] <= '9') st[++tot] = s[x++] - '0';
                change(); add();
                i = x - 1; continue;
            }   
        }
        if(s[i] >= '0' && s[i] <= '9'){
            memset(st,0,sizeof(st));
            int x= i; tot = 0;
            while(s[x] >= '0' && s[x] <= '9' ) st[++tot] = s[x++] - '0';
            change(); add();
            i = x - 1;
            continue; 
        }
        if(s[i] == '-' && s[i+1] == '-'){
            memset(st,0,sizeof(st));
            int x = i; cnt = 0; tot = 0;
            while(s[x] <'0' || s[x] >'9') x++,cnt++;
            while(s[x] >= '0' && s[x] <= '9') st[++tot] = s[x++] - '0';
            change(); mul(cnt); Add();
            i = x - 1;
            continue;
        }
        if(s[i] == '-' && s[i+1] == '('){
            memset(st,0,sizeof(st)); memset(que,0,sizeof(que));
            int x = i + 2; tot = 0; cnt = 0;
            while(s[x] >='0' && s[x] <='9') que[++cnt] = s[x++] - '0'; tchange();
            if(s[x] == ')'){
                x ++;
                while(s[x] >='0' && s[x] <='9') st[++tot] = s[x++] - '0';
                change();
            }
            Mmul(); Add();
            i = x - 1; continue;
        }
        if(s[i] == '-'){
            if(s[i+1] >= '0' && s[i+1] <= '9'){
                memset(st,0,sizeof(st));
                int x = i + 1; tot = 0;
                while(s[x] >= '0' && s[x] <= '9') st[++tot] = s[x++] - '0';
                change(); Add();
                i = x - 1; continue;
            }
        }   
    }
    if(check()){ cout<<"-"; jian1();}
    else jian2();

    for (int i = ans_len ; i >= 1 ; i --) cout<<ans[i]; 
    if(ans_len <= 0) cout<<0<<endl;
    return 0;
}
/*
+(255)10---3-(23)100
*/