問題概要
元素記号と重さの対応表が最初に与えられる。
その後、化学式が与えられるので、その重さを答える。
未知の元素が含まれている場合は"UNKNOWN"と出力する。
<molecule>::=<atom>|<atom><number>|'('<molecule>')'<number>|<molecule><molecule>
<atom>::=<capitaletter>|<capitaletter><smallletter>
<number>::=2|3|4|・・・|97|98|99
<capitalletter>::=A|B|C|・・・|X|Y|Z
<smallletter>::=a|b|c|・・・|x|y|z
解法
BNFに従って構文解析するだけ。
ソース
#include<iostream> #include<string> #include<map> #include<sstream> #include<cctype> using namespace std; typedef string::const_iterator Cursol; map < string , int > d; bool ok; int stoi(string s) { int v; stringstream ss(s); ss>>v; return v; } int Num(Cursol &c){ int ret; string s; s += *c++; if(isdigit(*c)) s += *c++; return stoi(s); } int Atom(Cursol &c){ int ret; string s; s += *c++; if(islower(*c)) s += *c++; ret = d[s]; if(ret == 0) ok = false; return ret; } int Molecule(Cursol &c){ if( *c == '\0' || *c == ')') return 0; int ret = 0; if(*c == '('){ ret = Molecule(++c) * Num(++c); }else if(isupper(*c)){ ret = Atom(c); if(isdigit(*c)) ret *= Num(c); } return ret + Molecule(c); } int main(){ string s; while(cin >> s , s != "END_OF_FIRST_PART"){ cin >> d[s]; } while(cin >> s , s != "0"){ Cursol c = s.begin(); ok = true; int ret = Molecule(c); if(ok) cout << ret << endl; else cout << "UNKNOWN" << endl; } }
0 件のコメント:
コメントを投稿