Luogu P2382 化學分子式 (模擬)
題目
題目背景
元首和元老正在共同努力學習化學,他們想讓電腦幫助他模擬分子式減輕負擔。請你幫他設計一個程序。
題目描述
你的任務是編寫一個能處理在虛擬的化學裏分子式的程序,在真正的化學裏,每個分子式描述分子包括一個或者多個原子,但是,它可能沒有真正的化學藥品。
下面是原子符號和分子式的定義:
分子中一個原子由一個原子符號表示,原子符號由單個大寫字母或者一個大寫字母和一個小寫字母組成。例如:H和He都是原子符號。
一個分子式是一個原子符號的非空序列,例如,\(HHHeHHHe\)是一個分子式,表示一個分子包括\(4\)個\(H\)和\(2\)個\(He\)。
為了方便起見,一段相同的式子,如\(x\cdots x\)
分子式的定義可以用一種規範的語言描述。簡而言之,分子式的語法描述如下:
分子:原子|原子數量|(分子)數字|分子 分子
原子:大寫字母|大寫字母 小寫字母
數字:\(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\)
最後一行僅一個零,表示輸入結束。
輸出格式:
輸出時一些行的序列,和輸入文件的第二部分行數相同。如果分子中的每一個原子都在原子表中出現,輸出一個整數,並表示分子質量。否者輸出UNKNOWN。不要輸出多余的字符。
輸入輸出樣例
輸入樣例:
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
輸出樣例:
14
UNKNOWN
98
7426
題解
第一次寫的時候用的棧來模擬, RE+WA, 索性全刪了重新用DFS寫了一遍就過了\(\cdots \cdots\)
純模擬, 不多說。
#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;
}
Luogu P2382 化學分子式 (模擬)