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

Iowa_BattleShip

2018-06-19 14:24:52

Solution

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