CCF CSP 竞赛试题——化学方程式(201912-3)

#include <bits/stdc++.h>
using namespace std;

unordered_map<string, int> parseFormulaEx(string::iterator s, string::iterator e) {
    unordered_map<string, int> cnt;
    // 计算系数
    int coef = 0;
    while (isdigit(*s)) {
        coef = coef * 10 + *s - '0';
        ++s;
    }
    coef = max(coef, 1);

    while (s != e) {
        unordered_map<string, int> temp;
        if (*s == '(') { // 找到匹配的')'
            auto p = s + 1;
            int cnt = 1;
            while (cnt != 0) {
                if (*p == '(')
                    ++cnt;
                else if (*p == ')')
                    --cnt;
                ++p;
            }
            temp = parseFormulaEx(s + 1, p - 1); // 去掉括号,递归
            s = p;
        } else {
            string element(1, *s);
            if (s + 1 != e && islower(*(s + 1))) {
                element.append(1, *(s + 1));
                ++s;
            }
            temp[element] = 1;
            ++s;
        }

        // 计算下标
        int subscript = 0;
        while (s != e && isdigit(*s)) {
            subscript = subscript * 10 + *s - '0';
            ++s;
        }
        subscript = max(subscript, 1);

        // 计入总量
        for (const auto& ele: temp) {
            cnt[ele.first] += subscript * ele.second;
        }
    }
    for (auto& ele: cnt) ele.second *= coef;
    return cnt;
}

unordered_map<string, int> parseExpr(string::iterator s, string::iterator e) {
    //cout << string(s, e) << endl;
    unordered_map<string, int> cnt;
    while (s != e) {
        auto p = find(s, e, '+');
        auto temp = parseFormulaEx(s, p);
        for (const auto& ele: temp) cnt[ele.first] += ele.second;
        if (p != e) ++p; // 跳过'+'
        s = p;
    }
    //for (const auto& ele: cnt) cout << ele.first << "\t" << ele.second << endl; cout << endl;
    return cnt;
}

bool isValid(string& equation) {
    auto eq = find(equation.begin(), equation.end(), '=');
    auto left = parseExpr(equation.begin(), eq);
    auto right = parseExpr(eq + 1, equation.end());
    if (left.size() != right.size()) return false;
    for (const auto& ele: left) {
        if (!right.count(ele.first) || right[ele.first] != ele.second) return false;
    }
    return true;
}

int main() {
    int n;
    cin >> n;
    string equation;
    while (n--) {
        cin >> equation;
        cout << (isValid(equation) ? "Y" : "N") << endl;
    }
    return 0;
}

// 程序鲁棒性很差,对‘不符合定义的化学方程式’或其他非法输入,将发生未定义行为

附:

1.in

11
H2+O2=H2O
2H2+O2=2H2O
H2+Cl2=2NaCl
H2+Cl2=2HCl
CH4+2O2=CO2+2H2O
CaCl2+2AgNO3=Ca(NO3)2+2AgCl
3Ba(OH)2+2H3PO4=6H2O+Ba3(PO4)2
3Ba(OH)2+2H3PO4=Ba3(PO4)2+6H2O
4Zn+10HNO3=4Zn(NO3)2+NH4NO3+3H2O
4Au+8NaCN+2H2O+O2=4Na(Au(CN)2)+4NaOH
Cu+As=Cs+Au

1.out

N
Y
N
Y
Y
Y
Y
Y
Y
Y
N
发布了33 篇原创文章 · 获赞 4 · 访问量 8727

猜你喜欢

转载自blog.csdn.net/Touchig/article/details/104052824