• Luogu P2382 化学分子式 (模拟)


    题目

    题目背景

    元首和元老正在共同努力学习化学,他们想让电脑帮助他模拟分子式减轻负担。请你帮他设计一个程序。

    题目描述

    你的任务是编写一个能处理在虚拟的化学里分子式的程序,在真正的化学里,每个分子式描述分子包括一个或者多个原子,但是,它可能没有真正的化学药品。

    下面是原子符号和分子式的定义:

    分子中一个原子由一个原子符号表示,原子符号由单个大写字母或者一个大写字母和一个小写字母组成。例如:H和He都是原子符号。

    一个分子式是一个原子符号的非空序列,例如,(HHHeHHHe)是一个分子式,表示一个分子包括(4)(H)(2)(He)

    为了方便起见,一段相同的式子,如(xcdots x)((n)(X)(2leq nleq 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
    ", num);
          }
        }
      }
      return 0;
    }
    
  • 相关阅读:
    Python中引用自定义类的方法
    使用js判断a是不是NaN 类型
    实现小数保留并四舍五入
    C# 生成全球唯一标识符GUID
    VS2008 激活
    Android 获取当前IP地址
    Android 双屏异显的实现
    用友系统的本币和原币
    .net core Json字符串的序列化和反序列化通用类源码,Newtonsoft和DataContractJsonSerializer性能对比
    建议收藏备用:.net core使用QRCoder生成普通二维码和带Logo的二维码详细使用教程,源码已更新至开源模板
  • 原文地址:https://www.cnblogs.com/forth/p/9773605.html
Copyright © 2020-2023  润新知