【题目传送门:】 [戳] (https://www.luogu.org/problemnew/show/P4711)

[算法分析:]

关于一个分子拆分后的产物,一共有三种情况:

  • 原子

  • 原子团

  • 水合物

关于原子的获取可以使用get_ele()函数,由于不是一位的元素就是两位的元素,只要看看这个大写字母的下一位是不是小写字母就行

返回获取的元素的string

关于系数的获取——使用函数get_num()——与快读的写法很接近,当没有系数的时候(处理后系数还是初始值没有被更新),系数是1

如何获取原子团

在出现左括号的时候使用get_group()函数

使用get_ele()不停地获取括号内的元素直到下一位是系数或者不是元素,

当下一位是系数的时候获取系数,并且获取这一位的元素,将获取的系数与获取的元素相乘。

其他:

  • 相对原子质量是实数,我们可以把他们都乘以10变成整数,有效地防止了被卡精度

  • 在处理水合物的时候记得水的相对分子质量不应是18而是180

  • 使用map来快速地获取每个元素的相对原子质量。

\([Code:]\)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std; const int MAXN = 1000 + 1; map<string, int> m; string str;
int e, c;
int ele[MAXN], coe[MAXN]; void init() {
m["H"] = 10;
m["C"] = 120;
m["N"] = 140;
m["O"] = 160;
m["F"] = 190;
m["Na"] = 230;
m["Mg"] = 240;
m["Al"] = 270;
m["Si"] = 280;
m["P"] = 310;
m["S"] = 320;
m["Cl"] = 355;
m["K"] = 390;
m["Ca"] = 400;
m["Mn"] = 550;
m["Fe"] = 560;
m["Cu"] = 640;
m["Zn"] = 650;
m["Ag"] = 1080;
m["I"] = 1270;
m["Ba"] = 1370;
m["Hf"] = 1785;
m["Pt"] = 1950;
m["Au"] = 1970;
m["Hg"] = 2010;
} int get_num(int k) {
int i = k + 2, num = 0;
while(str[i] >= '0' && str[i] <= '9')
num = (num << 3) + (num << 1) + str[i] - '0', ++i;
if(!num) num = 1;
coe[++c] += num;
return i;
} inline string get_ele(int &k) {
string ret;
ret += str[k];
if(str[k + 1] >= 'a' && str[k + 1] <= 'z')
ret += str[++k];
return ret;
} int get_group(int k) {
int i = k + 1, num = 0;
while(str[i] >= 'A' && str[i] <= 'Z' && str[i+1] != '_')
num += m[get_ele(i)], ++i;
if(str[i + 1] == '_' && str[i] != ')') {
i = get_num(i + 1);
i -= 4;
num += m[get_ele(i)] * coe[c];
i += 4;
coe[c--] = 0;
} ele[++e] = num;
return i;
} int get_h2o(int k) {
int i = k + 1, num = 0;
while(str[i] >= '0' && str[i] <= '9')
num = (num << 3) + (num << 1) + str[i] - '0', ++i;
if(!num) num = 1;
ele[++e] = 180, coe[++c] = num;
return i + 5;
} int main() {
init();
cin >> str;
int l = str.size();
for(int i=0; i<l; ++i) {
if(str[i] == '_') {
i = get_num(i);
continue;
}
if(str[i] == '(') {
i = get_group(i);
continue;
}
if(str[i] == '~') {
i = get_h2o(i);
continue;
}
if(str[i] >= 'A' && str[i] <= 'Z') {
ele[++e] = m[get_ele(i)];
if(str[i + 1] != '_') coe[++c] = 1;
}
}
int ans = 0;
for(int i=1; i<=e; ++i)
ans += ele[i] * coe[i];
cout << ans / 10.0;
}

【洛谷】【模拟+栈】P4711 「化学」相对分子质量的更多相关文章

  1. P4711 「化学」相对分子质量

    P4711 「化学」相对分子质量 给你一个字符串让你输出相对分子质量(弱智字符串模拟) 我比赛tm调了两个半小时啊QAQ 希望以后能增加代码力吧,纪念挂代码 Code #include<iost ...

  2. 洛谷 8 月月赛 & 「PMOI」Round · 04

    T1 T166167 「PMOI-4」人赢 题目大意 给一个数列的前两项分别为\(n\)和\(m\) 当\(i\geq3\)时\(a_i = a_{i-1}*a_{i-2}\)的个位 给定\(n\), ...

  3. 【luogu P4711 「化学」相对分子质量】 题解

    题目链接:https://www.luogu.org/problemnew/show/P4711 要细心模拟 #include <cstdio> #include <algorith ...

  4. LOJ 2249: 洛谷 P2305: bzoj 3672: 「NOI2014」购票

    题目传送门:LOJ #2249. 题意简述: 有一棵以 \(1\) 号节点为根节点的带边权的树. 除了 \(1\) 号节点的所有节点上都有人需要坐车到达 \(1\) 号节点. 除了 \(1\) 号节点 ...

  5. LOJ 2567: 洛谷 P3643: bzoj 4584: 「APIO2016」划艇

    题目传送门:LOJ #2249. 题意简述: 有 \(n\) 个位置,第 \(i\) 个位置可以填在 \([a_i,b_i]\) (\(1\le a_i\le b_i\le 10^9\))之间的整数, ...

  6. 洛谷 4768 LOJ 2718「NOI2018」归程

    [题解] 本题有多种做法,例如可持久化并查集.kruskal重构树等. kruskal重构树的做法是这样的:先把边按照海拔h从大到小的顺序排序,然后跑kruskal建立海拔的最大生成树,顺便建krus ...

  7. LOJ 2085: 洛谷 P1587: bzoj 4652: 「NOI2016」循环之美

    题目传送门:LOJ #2085. 两个月之前做的傻题,还是有必要补一下博客. 题意简述: 求分子为不超过 \(n\) 的正整数,分母为不超过 \(m\) 的正整数的所有互不相等的分数中,有多少在 \( ...

  8. 洛谷模拟NOIP考试反思

    洛谷模拟NOIP考试反思 想法 考了这么简单的试qwq然而依然emmmmmm成绩不好 虽然本次难度应该是大于正常PJ难度的但还是很不理想,离预估分数差很多qwq 于是就有了本反思嘤嘤嘤 比赛链接 原比 ...

  9. noip模拟9[斐波那契·数颜色·分组](洛谷模拟测试)

    这次考试还是挺好的 毕竟第一题被我给A了,也怪这题太简单,规律一眼就看出来了,但是除了第一题,剩下的我只有30pts,还是菜 第二题不知道为啥我就直接干到树套树了,线段树套上一个权值线段树,然后我发现 ...

随机推荐

  1. Java设计模式学习记录-命令模式

    前言 这次要介绍的是命令模式,这也是一种行为型模式.最近反正没有面试机会我就写博客呗,该投的简历都投了.然后就继续看书,其实看书也会给自己带来成就感,原来以前不明白的东西,书上已经给彻底的介绍清楚了, ...

  2. [转]git提交代码时遇到代码库有更新以及本地有更新的解决方法

    本文转自:https://blog.csdn.net/myphp2012/article/details/80519156 在多人协作开发时,经常碰到同事把最新修改推送到远程库,你在本地也做了修改,这 ...

  3. [转]Building a REST-Backend for Angular with Node.js & Express

    本文转自:https://malcoded.com/posts/angular-backend-express Angular is a single page application framewo ...

  4. 在C#中,如何连接已加密的Sqlite数据库

    对数据加密分两种,一种是对数据库本身进行加密,另一种是对数据表中的数据进行加密, 如果SQLite数据库加密,我这里使用的一个管理工具叫SQLiteDeveloper,如下就可以加密数据库 , 如果在 ...

  5. [android] 手机卫士读取联系人

    获取ContentResolver内容解析器对象,通过getContentResolver()方法 调用ContentResolver对象的query()方法,得到raw_contacts表里面的数据 ...

  6. 【Spring】详解spring事务属性

    Spring声明式事务让我们从复杂的事务处理中得到解脱.使得我们再也无需要去处理获得连接.关闭连接.事务提交和回滚等这些操作.再也无需要我们在与事务相关的方法中处理大量的try…catch…final ...

  7. 报错No active profile set, falling back to default profiles

    pom.xml加上下面两个依赖 <dependency> <groupId>org.springframework.boot</groupId> <artif ...

  8. js 前端有消息了 声音提示给用户

    前言:工作中有需求,在数据变更有变更时采用声音提示给用户,这里记录一下.转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9936180.html 网站地址:我的个 ...

  9. 【工具相关】web-HTML/CSS/JS Prettify的使用

    一,打开Sublime Text,代码如下面所示. 二,鼠标右键--->HTML/CSS/JS Prettify--->Prettify Code.代码如图所示,明显的代码变得整齐了.

  10. 即时消息服务框架(iMSF)应用实例之分布式事务三阶段提交协议的实现

    一,分布式事务简介 在当前互联网,大数据和人工智能的热潮中,传统企业也受到这一潮流的冲击,纷纷响应国家“互联网+”的战略号召,企业开始将越来越多的应用从公司内网迁移到云端和移动端,或者将之前孤立的IT ...