题目
题目背景
元首和元老正在共同努力学习化学,他们想让电脑帮助他模拟分子式减轻负担。请你帮他设计一个程序。
题目描述
你的任务是编写一个能处理在虚拟的化学里分子式的程序,在真正的化学里,每个分子式描述分子包括一个或者多个原子,但是,它可能没有真正的化学药品。
下面是原子符号和分子式的定义:
分子中一个原子由一个原子符号表示,原子符号由单个大写字母或者一个大写字母和一个小写字母组成。例如:H和He都是原子符号。
一个分子式是一个原子符号的非空序列,例如,\(HHHeHHHe\)是一个分子式,表示一个分子包括\(4\)个\(H\)和\(2\)个\(He\)。
为了方便起见,一段相同的式子,如\(x\cdots
x\)(\(n\)个\(X\),\(2\leq
n\leq 99\)),可以被缩写为\((X)_n\)。如果\(X\)是一个原子符号,那么括号可以省略。例如,\(HHHeHHHe\)也可以写作\(H_2HeH_2He\),\((HHHe)_2\),\((H_2He)_2\),\(((H)_2He)_2\)。
分子式的定义可以用一种规范的语言描述。简而言之,分子式的语法描述如下:
分子:原子|原子数量|(分子)数字|分子 分子 原子:大写字母|大写字母
小写字母
数字:\(2|3|4|5|\cdots|99|\)
大写字母:\(A|B|\cdots|Z|\)
小写字母:\(a|b|c|\cdots|z|\)
在我们这个虚拟的化学里的每一个原子都有自己的原子质量,给你原子的质量,你的程序必须输出一个用分子式表示的分子质量。分子的质量定义为所有包括的原子的质量之和。例如,假设\(H\)和\(He\)的原子质量为\(1\)和\(4\),那么\((H_2He)_2\)的分子量为\(12\)。
输入输出格式
输入格式:
输入由两部分组成。第一部分是原子表,由一些行组成,每行包括一个原子符号、一个或者多个空格,以及该原子的原子质量(\(\leq
1000\))。没有两行包含相同的原子符号。
第一部分最后仅包括一行字符串"END_OF_FIRST_PART"
。
第二部分是一些行的序列。每行是一个分子式,不多于\(80\)个字符,而且不包括空格。一个分子最多包括\(10^5\)个原子,一些分子中的原子可能没有在原子表中出现。
最后一行仅一个零,表示输入结束。
输出格式:
输出时一些行的序列,和输入文件的第二部分行数相同。如果分子中的每一个原子都在原子表中出现,输出一个整数,并表示分子质量。否者输出UNKNOWN。不要输出多余的字符。
输入输出样例
输入样例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| H 1 He 4 C 12 O 16 F 19 Ne 20 Cu 64 Cc 333 END_OF_FIRST_PART H2C (MgF)2As Cu(OH)2 H((CO)2F)99 0
|
输出样例:
题解
第一次写的时候用的栈来模拟, RE+WA,
索性全删了重新用DFS写了一遍就过了\(\cdots
\cdots\)
纯模拟, 不多说。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| #include <iostream> #include <map> #include <string> #include <cstdio> #include <cctype> std::map<std::string, int> elements; std::string matter; int cur, weight, length; inline int GetInt() { register int ret(0); while (cur < length && isdigit(matter[cur])) { ret = ret * 10 + matter[cur++] - '0'; } return ret ? ret : 1; } inline int Dfs() { register int ret(0); while (cur < length) { if (matter[cur] == '(') { ++cur; ret += Dfs(); } else if (matter[cur] == ')') { ++cur; return ret * GetInt(); } else { if (isalpha(matter[cur + 1]) && islower(matter[cur + 1])) { register std::string cur_element = std::string("") + matter[cur] + matter[cur + 1]; if (!elements.count(cur_element)) { return -2147483647; } ++++cur; ret += elements[cur_element] * GetInt(); } else { register std::string cur_element = std::string("") + matter[cur]; if (!elements.count(cur_element)) { return -2147483647; } ++cur; ret += elements[cur_element] * GetInt(); } } } return ret; } int main(int argc, char const *argv[]) { { register std::string element; while (std::cin >> element && element != "END_OF_FIRST_PART") { scanf("%d", &weight); elements[element] = weight; } while (std::cin >> matter && matter != "0") { cur = 0, length = matter.length(); register int num(Dfs()); if (num < 0) { puts("UNKNOWN"); } else { printf("%d\n", num); } } } return 0; }
|