CCF2019-12 化学方程式(模拟)

CCF2019-12 化学方程式(模拟)_第1张图片

思路:
就是一道很复杂的模拟题
每个化学元素的数目来源有3种:化合物最前面的数字mul,该元素后面的数字mul2,括号累计得到的数字mul3。

分别维护这三个值即可。

mul和mul2都可以在确定元素的时候算出来
而对于mul3,我们一开始就进行括号匹配,得到每一个左括号对应右括号后面的数字。那么之后遍历序列时,每经过一个左括号,mul3就乘上该左括号对应数目。每经过一次右括号,mul3就除以该括号对应的数目。

题外话:
改来改去都只有90分,最后无奈和别人代码对拍,最后发现还有一个很重要的条件:左右元素数目相同!

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

const int maxn = 5e3 + 7;

char s[10005];

map<int,int>dat1,dat2;

char check(char x) {
    if(x >= 'a' && x <= 'z') return true;
    return false;
}

bool Isnumber(char x) {
    return (x >= '0' && x <= '9');
}

void init() {
    dat1.clear();dat2.clear();
    int n = strlen(s + 1);
    stack<pair<int,char> >stk;
    for(int i = 1;i <= n;i++) {
        if(s[i] == '(') {
            stk.push({i,'('});
        }
        else if(s[i] == ')'){
            int pre = stk.top().first;stk.pop();
            int num = 0;
            while(Isnumber(s[i + 1])) {
                num = num * 10 + s[i + 1] - '0';
                i++;
            }
            dat1[pre] = max(num,1);
            dat2[i] = max(num,1);
        }
    }
}

void solve(map<string,int>&mp,int sta,int ed) {
    int now = 0,mul = 1,mul3 = 1;
    int left = 0;
    for(int i = sta;i <= ed;i++) {
        if(isalpha(s[i])) {
            string now;
            now += s[i];
            if(check(s[i + 1])) {
                i++;
                now += s[i];
            }
            int mul2 = 0;
            while(Isnumber(s[i + 1])) {
                mul2 = mul2 * 10 + s[i + 1] - '0';
                i++;
            }
            mul2 = max(mul2,1);
            mp[now] += mul * mul2 * mul3;
        }
        else if(Isnumber(s[i])) {
            int mul2 = 0;
            i--;
            while(Isnumber(s[i + 1])) {
                mul2 = mul2 * 10 + s[i + 1] - '0';
                i++;
            }
            mul = mul2;
        }
        else if(s[i] == '(') {
            left++;
            mul3 *= dat1[i];
        }
        else if(s[i] == ')') {
            left--;
            while(Isnumber(s[i + 1])) {
                i++;
            }
            mul3 /= dat2[i];
        }
        else {
            mul = 1;
        }
    }
}

int main() {
    int T;scanf("%d",&T);
    while(T--) {
        map<string,int>mp1,mp2;
        scanf("%s",s + 1);
        init();
        int pos = 0;
        int n = (int)strlen(s + 1);
        for(int i = 1;i <= n;i++) {
            if(s[i] == '=') {
                pos = i;break;
            }
        }
        solve(mp1,1,pos);
        solve(mp2,pos + 1,n);
        
        int flag = 1;
        if(mp1.size() != mp2.size()) flag = 0;
        for(auto &it : mp1) {
            string x = it.first;
            if(mp1[x] != mp2[x]) {
                flag = 0;
                break;
            }
        }
        if(flag)printf("Y\n");
        else printf("N\n");
    }
    return 0;
}

你可能感兴趣的:(#,其他比赛题目)