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

这题么,绝对没有蓝题难度,我个人认为黄题封顶,毕竟这是少见的不毒瘤的模拟题。
这题很良心的没有括号嵌套,这样就不用递归那么麻烦了,直接读进来扫一遍即可,具体还是看代码吧。

#include<cstdio>
#include<cstring>
#include<string>
#include<map>
using namespace std;
char a[110],b[10];//a是读进来的整个字符串,b是临时字符数组,存当前元素
int l,ll;//l为a的长度,ll为b的长度
map<string,double>mp;//map大法好,存元素对应的相对原子质量
int cs(int &i)//类似快读,将字符转化为数字,同时将主函数的i同步扫过
{
    int x=0;
    for(;a[i]>='0'&&a[i]<='9';i++)
        x=x*10+(a[i]-'0');
    return x;
}
double js(int &i)//计算当前扫到的元素的相对原子质量,同样将主函数的i同步
{
    double s=0;//记录质量
    memset(b,0,sizeof(b));//清空临时字符数组
    for(ll=-1;((a[i]>='A'&&a[i]<='Z')||(a[i]>='a'&&a[i]<='z'))&&(ll<0||(ll>=0&&(a[i]>='a'&&a[i]<='z')));i++)
        b[++ll]=a[i];
    //找到目前扫到的元素
    //因为元素开头必是大写字母
    //所以当扫到的字符不为小写字母(已将这个元素的首字母读入)说明当前元素已扫完
    if(a[i]=='_')//若这元素后面有下标,就将数字读入并乘上该元素相对原子质量
    {
        i+=2;//直接跳过'_{'
        s+=mp[b]*cs(i);
    }
    else//若没有下标,直接累加上该元素相对原子质量
    {
        s+=mp[b];
        i--;
    }
    return s;
}
int main()
{
    int i,o;
    double s,k;
    mp["H"]=1;//以下为初始化
    mp["C"]=12;
    mp["N"]=14;
    mp["O"]=16;
    mp["F"]=19;
    mp["Na"]=23;
    mp["Mg"]=24;
    mp["Al"]=27;
    mp["Si"]=28;
    mp["P"]=31;
    mp["S"]=32;
    mp["Cl"]=35.5;
    mp["K"]=39;
    mp["Ca"]=40;
    mp["Mn"]=55;
    mp["Fe"]=56;
    mp["Cu"]=64;
    mp["Zn"]=65;
    mp["Ag"]=108;
    mp["I"]=127;
    mp["Ba"]=137;
    mp["Hf"]=178.5;
    mp["Pt"]=195;
    mp["Au"]=197;
    mp["Hg"]=201;
    scanf("%s",a);//合法字符串直接%s读入
    l=strlen(a);//计算长度
    for(i=0;i<l;i++)//直接扫
    {
        if(a[i]>='A'&&a[i]<='Z')//若为大写字母,说明扫到一个元素,直接累加上去
            s+=js(i);
        if(a[i]=='(')//若为左括号,则计算括号内的质量
        {
            i++;//跳过'('
            for(k=0;a[i]!=')';i++)//因为没有括号嵌套或是水合物,里面必是各种元素,所以直接累加至遇到')'
                k+=js(i);
            if(a[i+1]=='_')//判断是否有下标
                s+=k*cs(i+=3);//有则将数字乘上,i+=3是为跳过'_{'
            else
                s+=k;//没有就直接加上
        }
        if(a[i]=='~')//若有水合物
        {
            i++;//跳过'~'
            if(a[i]=='H')//若为'H',说明只含一个水分子,直接累加
                s+=18;//一个水分子的相对分子质量为18
            else
                s+=cs(i)*18;//不为'H'说明有数量,将其乘上即可
            break;//因为水合物肯定在最后,所以直接跳出即可
        }
    }
    o=s;//利用int强制转换来判断是否有.5
    if(o==s)
        printf("%d",o);
    else
        printf("%.1f",s);
    return 0;
}

发表于 2018-06-19 14:24:52 in 题解