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

· · 题解

一道没怎么有技术含量的大模拟

直接上代码:

#include<map>//map大法好
#include<cstring>
#include<iostream>
using namespace std;
map<string,double> ma;
string s;
double ans,nans;//ans是最终答案,nans是当前部分临时的答案(比如括号内的一部分)
bool A(char c){return (c>='A' && c<='Z');}//判断是否为大写字母
bool a(char c){return (c>='a' && c<='z');}//判断是否为小写字母
int main()
{
    ma["H"]=1;ma["C"]=12;ma["N"]=14;ma["O"]=16;
    ma["F"]=19;ma["Na"]=23;ma["Mg"]=24;ma["Al"]=27;
    ma["Si"]=28;ma["P"]=31;ma["S"]=32;ma["Cl"]=35.5;
    ma["K"]=39;ma["Ca"]=40;ma["Mn"]=55;ma["Fe"]=56;
    ma["Cu"]=64;ma["Zn"]=65;ma["Ag"]=108;ma["I"]=127;
    ma["Ba"]=137;ma["Hf"]=178.5;ma["Pt"]=195;
    ma["Au"]=197;ma["Hg"]=201;
    //先预处理一下元素相对分子质量
    cin>>s;//读入字符串
    int l=s.length(),now=0;//l为字符串长度,now是当前的位置
    while(now<l){
        if(s[now]=='('){//如果读到左括号
            now++;//位置+1
            ans+=nans;//把临时答案加到ans里
            nans=0;//临时答案清零
            while(s[now]!=')'){//如果当前不是右括号
                while(A(s[now])){//如果是元素开头(大写字母)
                    string ss="";//定义一个字符串
                    ss+=s[now];
                    while(a(s[++now])){//小写字母说明还是同一个元素
                        ss+=s[now];//储存
                    }
                    if(s[now]=='_'){//'_'说明有系数
                        nans+=(s[now+2]-'0')*ma[ss];
                    //往后数第二个是系数,乘起来加到临时变量里去
                        now+=4;//位置后移
                    }
                    else nans+=ma[ss];//map映射,加入总答案
                } 
            }
        }
        else if(A(s[now]))//与上面相同,不解释
            while(A(s[now]))
            {
                string ss="";
                ss+=s[now];
                while(a(s[++now])){
                    ss+=s[now];
                }
                if(s[now]=='_'){
                    nans+=(s[now+2]-'0')*ma[ss];
                    now+=4;
                }
                else nans+=ma[ss];
            } 
        else if(s[now]=='_'){
            ans+=(s[now+2]-'0')*nans;
            now+=4;nans=0;//注意这里因为不在括号内,多了一个清零
        }
        else if(s[now]=='~'){//如果是水合物
            ans+=nans;nans=0;//先把临时答案加上并清零
            if(s[++now]>='1' && s[now]<='9')//如果第一位是数字
                while(s[now]>='0' && s[now]<='9')
                    nans=nans*10+s[now++]-'0';//就计算系数
            else nans=1;//不是数字就默认为一
            ans+=nans*18;答案加上系数乘以水的相对分子质量18
            nans=0;//清空临时答案
            now+=6;//位置后移(其实也可以直接break)
        }
    }
    cout<<ans+nans;输出答案加上临时答案
    return 0;//好习惯
}

眼睁睁看着这道题被刷成提高+/省选-

其实没有那么难 , 稍微细心一点就能做对