题解 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;//好习惯
}
眼睁睁看着这道题被刷成提高+/省选-
其实没有那么难 , 稍微细心一点就能做对