题解:P4711 「化学」相对分子质量
暴力模拟,直接用一个map储存各个元素的相对原子质量,然后除去括号等运算符即可。
虽然题目里只要求20几个元素,但是如果你想像我一样装个逼的话就可以把所有的元素写进去
做的时候也是直接(加钠),差一点点就TLE了。
大家逝一逝 (NH_{4})(NO_{3}) ,你会发现,10个题解会有11个答案。
#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["He"]=4;mp["Li"]=7;mp["Be"]=9;mp["B"]=11;mp["C"]=12;mp["N"]=14;mp["O"]=16;mp["F"]=19;mp["Ne"]=20;mp["Na"]=23;mp["Mg"]=24;mp["Al"]=27;mp["Si"]=28;mp["P"]=31;mp["S"]=32;mp["Cl"]=35.5;mp["Ar"]=40;mp["K"]=39;mp["Ca"]=40;mp["Sc"]=45;mp["Ti"]=48;mp["V"]=51;mp["Cr"]=52;mp["Mn"]=55;mp["Fe"]=56;mp["Co"]=59;mp["Ni"]=59;mp["Cu"]=64;mp["Zn"]=65;mp["Ga"]=70;mp["Ge"]=73;mp["As"]=75;mp["Se"]=79;mp["Br"]=80;mp["Kr"]=84;mp["Rb"]=85;mp["Sr"]=88;mp["Y"]=90;mp["Nb"]=91;mp["Mo"]=93;mp["Tc"]=99;mp["Ru"]=101;mp["Rh"]=103;mp["Pd"]=106;mp["Ag"]=108;mp["Cd"]=112;mp["In"]=115;mp["Sn"]=119;mp["Sb"]=122;mp["Te"]=128;mp["I"]=127;mp["Xe"]=131;mp["Cs"]=133;mp["Ba"]=137;mp["La"]=139;mp["Ce"]=141;mp["Pr"]=141;mp["Nd"]=144;mp["Pm"]=147;mp["Sm"]=150;mp["Eu"]=152;mp["Gd"]=157;mp["Tb"]=159;mp["Dy"]=162.5;mp["Ho"]=165;mp["Er"]=167;mp["Tm"]=169;mp["Yb"]=173;mp["Lu"]=175;mp["Hf"]=178.5;mp["Ta"]=181;mp["W"]=184;mp["Re"]=186;mp["Os"]=190;mp["Ir"]=192;mp["Pt"]=195;mp["Au"]=197;mp["Hg"]=201;mp["Tl"]=204;mp["Pb"]=207;mp["Bi"]=209;mp["Po"]=209;mp["At"]=201;mp["Rn"]=222;mp["Fr"]=223;mp["Ra"]=226;mp["Ac"]=227;mp["Th"]=232;mp["Pa"]=231;mp["U"]=238;mp["Np"]=237;mp["Pu"]=244;mp["Am"]=243;mp["Cm"]=247;mp["Bk"]=247;mp["Cf"]=251;mp["Es"]=254;mp["Fm"]=257;mp["Md"]=258;mp["No"]=259;mp["Lr"]=260;mp["Rf"]=261;mp["Db"]=262;mp["Sg"]=263;mp["Bh"]=262;mp["Hs"]=265;mp["Mt"]=266;mp["Ds"]=269;mp["Rg"]=272;mp["Cn"]=277;mp["Nh"]=284;mp["Fl"]=289;mp["Mc"]=288;mp["Lv"]=292;mp["Ts"]=293;mp["Og"]=294;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是为跳过'_{'elses+=k;//没有就直接加上}if(a[i]=='~')//若有水合物{i++;//跳过'~'if(a[i]=='H')//若为'H',说明只含一个水分子,直接累加s+=18;//一个水分子的相对分子质量为18elses+=cs(i)*18;//不为'H'说明有数量,将其乘上即可break;//因为水合物肯定在最后,所以直接跳出即可}}o=s;//利用int强制转换来判断是否有.5if(o==s)printf("%d",o);elseprintf("%.1f",s);return 0;
}