题解 P4711 【「化学」相对分子质量】

· · 题解

这题有这么繁吗? 每次读入一个内容并判断:

(1):‘~’,往后看,是数字就取出来乘以18;是‘H’就直接加上18;

(2):‘(’,处理内部内容和外侧一样;

(3):字母,取出这种元素;

(4):数字,取出来就可以。

(5):其它字符无需考虑。

其中遇到前三种情况时累加进答案,最后再把没加的加上。

#include<bits/stdc++.h>
using namespace std;
map<string, double> chem;
void init() {
    chem["H"] = 1;
    chem["C"] = 12;
    chem["N"] = 14;
    chem["O"] = 16;
    chem["F"] = 19;
    chem["Na"] = 23;
    chem["Mg"] = 24;
    chem["Al"] = 27;
    chem["Si"] = 28;
    chem["P"] = 31;
    chem["S"] = 32;
    chem["Cl"] = 35.5;
    chem["C"] = 12;
    chem["K"] = 39;
    chem["Ca"] = 40;
    chem["Mn"] = 55;
    chem["Fe"] = 56;
    chem["Cu"] = 64;
    chem["Zn"] = 65;
    chem["Ag"] = 108;
    chem["I"] = 127;
    chem["Ba"] = 137;
    chem["Hf"] = 178.5;
    chem["Pt"] = 195;
    chem["Au"] = 197;
    chem["Hg"] = 201;
}
string s;
double ans = 0;
int num = 1;
string ele;
double szele;
int into(int p0) {
    int p;
    for (p = p0; s[p] != ')'; p++) {
        if (s[p] >= 'A' && s[p] <= 'Z') {
            szele += chem[ele] * num;
            num = 1, ele.clear();
            ele.push_back(s[p]);
            if (s[p+1] >= 'a' && s[p+1] <= 'z')
                ele.push_back(s[++p]);
        }
        if (s[p] >= '0' && s[p] <= '9') {
            num = s[p] - '0';
            while (s[p+1] >= '0' && s[p+1] <= '9') num = num * 10 + s[++p] - '0';
        }
    }
    szele += chem[ele] * num;
    return p;
}
int main() {
    init();
    cin >> s;
    for (int p = 0; p < s.size(); p++) {
        if (s[p] == '~') {
            if (!szele) szele = chem[ele];
            ans += szele * num;
            szele = 0, num = 1, ele.clear();
            if (s[p+1] == 'H') {
                ans += 18;
                break;
            }
            num = 0;
            while (s[p+1] != 'H') num = num * 10 + s[++p] - '0';
            ans += num * 18;
            break;
        }
        if (s[p] == '(') {
            if (!szele) szele = chem[ele];
            ans += szele * num;
            szele = 0, num = 1, ele.clear();
            p = into(p + 1);
            continue;
        }
        if (s[p] >= 'A' && s[p] <= 'Z') {
            if (!szele) szele = chem[ele];
            ans += szele * num;
            szele = 0, num = 1, ele.clear();
            ele.push_back(s[p]);
            if (s[p+1] >= 'a' && s[p+1] <= 'z')
                ele.push_back(s[++p]);
        }
        if (s[p] >= '0' && s[p] <= '9') {
            num = s[p] - '0';
            while (s[p+1] >= '0' && s[p+1] <= '9') num = num * 10 + s[++p] - '0';
        }
    }
    if (!szele) szele = chem[ele];
    ans += szele * num; 
    cout << ans << endl;
    return 0;
}