zoukankan      html  css  js  c++  java
  • 【洛谷】【模拟+栈】P4711 「化学」相对分子质量

    【题目传送门:】 [戳] (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;
    }
    
  • 相关阅读:
    Mac系统下安装和卸载HomeBrew的方法
    .NET笔试题集(五)
    .NET笔试题集(四)
    .NET笔试题集(二)
    .NET笔试题集(三)
    .NET笔试题集(一)
    C# 文件操作方法
    MD5 加密的两种方法
    jquery 元素选择器集合
    Jquery元素追加和删除
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9202659.html
Copyright © 2011-2022 走看看