1. 程式人生 > >Luogu P2382 化學分子式 (模擬)

Luogu P2382 化學分子式 (模擬)

學習 方便 iostream char line eight ctype 字符串 ots

題目

題目背景

元首和元老正在共同努力學習化學,他們想讓電腦幫助他模擬分子式減輕負擔。請你幫他設計一個程序。

題目描述

你的任務是編寫一個能處理在虛擬的化學裏分子式的程序,在真正的化學裏,每個分子式描述分子包括一個或者多個原子,但是,它可能沒有真正的化學藥品。

下面是原子符號和分子式的定義:

分子中一個原子由一個原子符號表示,原子符號由單個大寫字母或者一個大寫字母和一個小寫字母組成。例如: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。不要輸出多余的字符。

輸入輸出樣例

輸入樣例:
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 化學分子式 (模擬)