Luogu4711 「化学」相对分子质量

模拟题,写一些比较细节的东西的时候多考虑一下就行了

感觉分各种函数写还是很爽的

注意一些可能需要特判的情况细节

比如说为了偷懒把 char_to_int 写成了读优的形式
虽然可以少写几个 ++ptr 但是在它没有数字的时候就一路找下去了
挺显然的 bug 其实


代码:

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cstdio>
#include <cmath>
using namespace std;
 
const int MAX_N = 105, MAX_SIZ = 130;
 
int n, len;
double w[MAX_SIZ][MAX_SIZ];
char s[MAX_N];
 
inline void init() {
    w['H'][0] = 1; w['I'][0] = 127; w['C'][0] = 12;
    w['N'][0] = 14; w['O'][0] = 16; w['F'][0] = 19;
    w['P'][0] = 31; w['S'][0] = 32; w['K'][0] = 39;
    w['N']['a'] = 23; w['M']['g'] = 24; w['A']['l'] = 27;
    w['S']['i'] = 28; w['C']['l'] = 35.5; w['C']['a'] = 40;
    w['M']['n'] = 55; w['F']['e'] = 56; w['C']['u'] = 64;
    w['Z']['n'] = 65; w['A']['g'] = 108; w['B']['a'] = 137;
    w['H']['f'] = 178.5; w['P']['t'] = 195; w['A']['u'] = 197;
    w['H']['g'] = 201;
    return;
}
inline int get_int(int &pos) {
    register int x = 0;
    while (!isdigit(int(s[pos]))) ++pos;
    while (isdigit(int(s[pos]))) {
        x = x * 10 + (int(s[pos]) ^ 48);
        ++pos;
    }
    return x;
}
inline double get_ele(int &pos) {
    register int fir = 0, sec = 0;
    fir = s[pos];
    ++pos;
    if (islower(s[pos])) {
        sec = s[pos];
        ++pos;
    }
    return w[fir][sec];
}
double get_wei(int &pos, bool has_brak) {
    double tot_wei = 0, blk_wei = 0, tims = 1, tmp = 0;
    while (pos <= len && (!has_brak || (has_brak && s[pos] != ')'))) {
        if (isupper(int(s[pos]))) {
            blk_wei = get_ele(pos);
            tot_wei += blk_wei;
        } else if (s[pos] == '_') {
            tot_wei += (get_int(pos) - 1) * blk_wei;
        } else if (s[pos] == '(') {
            ++pos;
            blk_wei = get_wei(pos, 1);
            tot_wei += blk_wei;
        } else if (s[pos] == '~') {
            if (isdigit(s[pos + 1])) {
                tims = get_int(pos);
                pos += 3;
            } else {
                tims = 1;
            }
            tmp = get_int(pos);
            ++pos;
            tmp += 16;
            blk_wei = tmp * tims;
            ++pos;
            tot_wei += blk_wei;
        } else ++pos;
    }
    return tot_wei;
}
 
int main() {
    init();
    scanf("%s", s + 1);
    len = strlen(s + 1);
    register int bgn = 1;
    register double ans = get_wei(bgn, 0);
    if (ceil(ans) - ans < 1e-3) {
        printf("%.0lf", ans);
    } else printf("%.1lf", ans);
    return 0;
}

  

 

posted @ 2018-11-05 12:42  EvalonXing  阅读(214)  评论(0编辑  收藏  举报