博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P4711 「化学」相对分子质量
阅读量:6714 次
发布时间:2019-06-25

本文共 3628 字,大约阅读时间需要 12 分钟。

月赛的经典模拟题

模拟水题调到要死,但是还是能1A,还是很爽的。


这道题可以直接用scanf读入一行,用fgets会读入一个'\n',我不喜欢。

然后用一个变量从左到右扫一遍。

如果读到了大写字母,那么你现在肯定在读一个元素的名称。判断是否有小写字母,名字完了之后判断是不是有下标数字。

读数字是一件挺频繁的工作,建议封装成函数,很爽。

有一个难点是原子团,不过不难发现:用括号括起来的原子团一定会有下标!这是常识

处理原子团的时候应该单独计局部重量,到最后读完整个原子团的时候再加到总答案里面去。

最后的结晶水只需要读个数字走人就好了。如果没数字就根本不用读就是1。

没有数字默认的量就是1,这个最好设置着保险。

多debug看一下程序怎么跑,有时就能发现你的逻辑错误所在。

代码:

#include
#include
#include
const int maxn = 105;char ch[maxn];int len;double mass(char ch1, char ch2){ if(ch1 == 'H' && ch2 == 0) return 1; else if(ch1 == 'C' && ch2 == 0) return 12; else if(ch1 == 'N' && ch2 == 0) return 14; else if(ch1 == 'O' && ch2 == 0) return 16; else if(ch1 == 'F' && ch2 == 0) return 19; else if(ch1 == 'N' && ch2 == 'a') return 23; else if(ch1 == 'M' && ch2 == 'g') return 24; else if(ch1 == 'A' && ch2 == 'l') return 27; else if(ch1 == 'S' && ch2 == 'i') return 28; else if(ch1 == 'P' && ch2 == 0) return 31; else if(ch1 == 'S' && ch2 == 0) return 32; else if(ch1 == 'C' && ch2 == 'l') return 35.5; else if(ch1 == 'K' && ch2 == 0) return 39; else if(ch1 == 'C' && ch2 == 'a') return 40; else if(ch1 == 'M' && ch2 == 'n') return 55; else if(ch1 == 'F' && ch2 == 'e') return 56; else if(ch1 == 'C' && ch2 == 'u') return 64; else if(ch1 == 'Z' && ch2 == 'n') return 65; else if(ch1 == 'A' && ch2 == 'g') return 108; else if(ch1 == 'I' && ch2 == 0) return 127; else if(ch1 == 'B' && ch2 == 'a') return 137; else if(ch1 == 'H' && ch2 == 'f') return 178.5; else if(ch1 == 'P' && ch2 == 't') return 195; else if(ch1 == 'A' && ch2 == 'u') return 197; else if(ch1 == 'H' && ch2 == 'g') return 201; else return 0;}std::pair
read(int pos){ int ans = 0; while(pos < len) { if(ch[pos] < '0' || ch[pos] > '9') break; ans = ans * 10 + ch[pos] - '0'; pos++; } return std::make_pair(ans, pos);}double solve(){ len = strlen(ch); double total_weight = 0; bool in_yuanzituan = false; double yuanzituan_weight = 0; char name[2] = {0}; int num = 1; for(int i = 0; i < len; ) { int pos = i; if(ch[pos] >= 'A' && ch[pos] <= 'Z') { // 开始读入元素名 name[0] = ch[i]; num = 1; if(ch[i + 1] >= 'a' && ch[i + 1] <= 'z')// 两个字母的 { name[1] = ch[i + 1]; if(ch[i + 2] == '_') { std::pair
pii = read(i + 4); num = pii.first; i = pii.second + 1; } else i += 2; } else if(ch[i + 1] == '_')// 一个字母但有数字的 { name[1] = 0; std::pair
pii = read(i + 3); num = pii.first; i = pii.second + 1; } else// 一个字母还没数字 { name[1] = 0; i++; } //结算 if(in_yuanzituan) yuanzituan_weight += mass(name[0], name[1]) * num; else total_weight += mass(name[0], name[1]) * num; } else if(ch[pos] == '(') { in_yuanzituan = true; i++; } else if(ch[pos] == ')') { std::pair
pii = read(pos + 3); num = pii.first; i = pii.second + 1; total_weight += yuanzituan_weight * num; in_yuanzituan = false; yuanzituan_weight = 0; } else if(ch[pos] == '~')// 后面是水合物 { num = 1; if(ch[pos + 1] >= '0' && ch[pos + 1] <= '9') { num = read(pos + 1).first; } total_weight += 18 * num; break; } } // how to do? return total_weight;}int main(){ scanf("%s", ch); double ans = solve(); int temp = ans; if(ans - temp < 1e-5) printf("%.0lf\n", ans); else printf("%.1lf\n", ans); return 0;}

转载于:https://www.cnblogs.com/Garen-Wang/p/9926123.html

你可能感兴趣的文章
两句话笔记--架构学习之一:并发基础课程(2)
查看>>
LINUX概念与常识
查看>>
SqlServer 添加用户 添加角色 分配权限
查看>>
HBase解决Region Server Compact过程占用大量网络出口带宽的问题
查看>>
Shell编程(基础)
查看>>
CSS3的线性渐变(linear-gradient)
查看>>
环境变量
查看>>
K盘显示文件系统变没,要怎样恢复资料
查看>>
windows常用命令整理
查看>>
使用andbug的monitor命令
查看>>
php-cgi进程占用cpu资源过大原因分析及解决
查看>>
CentOS/RedHat上安装man手册
查看>>
我的友情链接
查看>>
log4j配置
查看>>
去掉Intel集成显卡的桌面右键菜单
查看>>
我的友情链接
查看>>
MediaPlayer播放网络视频
查看>>
面试的时候你感觉受到尊重了吗?
查看>>
LNMP - nginx用户认证
查看>>
redis主从配置
查看>>