【题目传送门:】 [戳] (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. C# ListBox 自动滚动到底部 方法:

    在ListBox中添加一条记录(ListBox.Items.Add方法)后,滚动条会自动回到顶部.我们可能更希望它自动滚动到底部,简要介绍几种方法. 方法一: this.listBox1.Items. ...

  2. [转]【Angular4】基础(二):创建组件 Component

    本文转自:https://blog.csdn.net/u013451157/article/details/79445138 版权声明:本文为博主原创文章,未经博主允许不得转载. https://bl ...

  3. LInux Crontab及命令

    定时任务(cron job)被用于安排那些需要被周期性执行的命令.利用它,你可以配置某些命令或者脚本,让它们在某个设定的时间内周期性地运行.cron 是 Linux 或者类 Unix 系统中最为实用的 ...

  4. 关于 IdentityServer 部署到生产环境相关问题踩坑记录

    Idsr 定义了几种模式适用于不同的场景: // // 摘要: // OpenID Connect flows. public enum Flows { // // 摘要: // authorizat ...

  5. git 出现gnome-ssh-askpass:32737

    今天在git push origin master时,竟然出现了错误 (gnome-ssh-askpass:32737): Gtk-WARNING **: cannot open display: e ...

  6. CSS--使用Animate.css制作动画效果

    一 使用Animate.css动画 // 通过@import引入外部CSS资源; // 引入线上图片及JS文件; // 通过更改CSS类名生成不同类型的CSS3动画;   <!DOCTYPE h ...

  7. wepy里面两种不同的写回调函数的方法

    方案一const getHelpCenter = createAction(GET_HELP_CENTER, () => request('api/hisense/article/menu/li ...

  8. SAP 官网中文帮助文件&BP中文资料汇总

    系统 描述 版本 连接 SAP ME  制造执行 SAP Manufacturing Execution (SAP ME) 15.0 点击我 SAP ECC EHP6 财务部分 SAP ERP 6.0 ...

  9. JMeter JMeter远程分布式联机性能测试

    JMeter远程分布式联机性能测试   by:授客 QQ:1033553122 测试环境 apache-jmeter-2.13 Java JDK版本:1.8 1.  JMeter分布式测试简介 当一个 ...

  10. flow-vue.js移动端效果

    得益于vue.js和element,以及vue-element-extends在线表格编辑.前后端分离的后端用golang+beego框架,服务器采用腾讯云. vue的自适应做的很好,只要将侧栏加一行 ...