算法竞赛入门经典 习题3-2 UVa1586 molar-mass 题解

原题 [UVaoj 1586 molar-mass]

题目翻译
  • 给出 T T T 个分子式 s s s ( 0 < ∣ s ∣ < 80 0<|s|<80 0<s<80 ),计算分子量

    科普(对于化学小白): C , H , O , N C,H,O,N C,H,O,N 原子量分别为 12.01 , 1.008 , 16 , 14.01 12.01,1.008,16,14.01 12.01,1.008,16,14.01


样例输入 (想想为啥要给)
4
C
C6H5OH
NH2CH2COOH
C12H22O11

样例输出
12.010
94.108
75.070
342.296

题目分析
  • 一开始的思路
    • 读一个字母读一个数字,然后一乘,累加即可
  • 看完样例后的思考
    • 这题**好坑啊!

    • 这道题的几个坑:

      1. 有形如 C10 的分子量(即系数为多位数)
      2. 有形容 C 的分子量(即系数为 1 1 1,忽略不写)
      3. 输出保留 3 3 3 位小数
    • 于是 ···

      • 从第一位开始,找到字母后标记当前索引值 k k k

      • 向后遍历,若 s [ i ] s[i] s[i] 为数字(即 ′ 0 ′ ≤ s [ i ] ≤ ′ 9 ′ '0' \leq s[i] \leq '9' 0s[i]9 ),在累加器 n n n 添加后添加一位 s [ i ] s[i] s[i]

        科普(对于初学者):

        1. n n n 后添加一位 m m m ,可参考以下代码:
        n *= 10;
        n += m;
        
        1. 将一位数字符 c h ch ch 转换为数字( i n t int int )形式,可参考以下代码:

          int ch_int = ch - '0';
          
      • s [ k + 1 ] s[k+1] s[k+1] 是字母,即 s [ k ] s[k] s[k] 系数为 1 1 1、忽略不写的情况,则默认 n = 1

      • n ⋅ g e t ( m ) n·get(m) nget(m) 的结果加到答案 a n s ans ans 中 ( g e t ( m ) get(m) get(m) m m m 的分子量)

      • 遍历完字符串后,保留 3 3 3 位小数输出 a n s ans ans

        科普:有关保留小数点输出的相关内容,详见 [c++保留小数_模 块的博客-CSDN博客]


AC代码
#include<iostream>
#include<iomanip>
#include<string.h>
using namespace std;
int main()
{
	double mm[100];  // 存储分子的分子量
	mm['C'] = 12.01;
	mm['H'] = 1.008;
	mm['O'] = 16;
	mm['N'] = 14.01;
	
	int T;
	cin>>T; 
	while(T--)
	{
		string s;
		cin>>s;
		double ans = 0;
		for(int i = 0; i < s.length(); )
		{
			int k = i, n = 0;
			double m = mm[s[i]];
			i++;
			while((s[i] >= '0' && s[i] <= '9') && i < s.length())
			{
				n *= 10;
				n += s[i] - '0';
				i++;
			}
			i--;
			if(i == k) n = 1;
			ans += m * n;
			i++;
		}
		cout<<fixed<<setprecision(3)<<ans<<endl;
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值