恩这题其实并没有那么难,根本没有必要搞什么单调栈什么的,所以我来一发很短的题解。
本题的思路就是逐个击破,我的思路是这样的:
1.元素
对于单个元素的处理应该是很简单的,因为我们有强大的map,一个表就结束了。
2.下标
这里我主要分两种情况看:
只需要保存每个元素的值(last),如果发现下标就把已经加到ans里的last减掉,重新加上last×下标系数就可以了。
这个等会会在原子团的部分里解释
3.原子团
这个对于原子团中可能出现的嵌套问题,我选择了递归解决
原子团中的原子跟原子团外的原子是一个解决方法(原子+下标)
然后接下来就是原子团的下标了
这个问题需要我们对原子团中的运算结果进行一个tmp的保存,然后在退出函数之前检查外面有没有下标,有的话立即解决。
4.水合物
这个就很简单了,检测到~后直接计算系数,然后乘以18(H_{2}O的值)就可以了
具体的一些坑点会在代码里说
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| #include <bits/stdc++.h> using namespace std; double ans,last; string a; map <string,double> mp; inline void start(){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;} int ys(int k){ string s="";int j=k+1;s+=a[k]; for (;a[j]>='a'&&a[j]<='z';j++)s+=a[j]; ans+=last=mp[s]; return j; } int xb(int k){ int j=k+2,s=0; for (;a[j]>='0'&&a[j]<='9';j++)s=s*10+a[j]-'0'; ans-=last,ans+=last*s; return j; } double tmp,tlast; int xbk(int k){ int j=k+2,s=0; for (;a[j]>='0'&&a[j]<='9';j++)s=s*10+a[j]-'0'; tmp-=tlast,tmp+=tlast*s; return j; } int ysk(int k){ string s="";int j=k+1;s+=a[k]; for (;a[j]>='a'&&a[j]<='z';j++)s+=a[j]; tmp+=tlast=mp[s]; return j; } inline int kh(int k){ int j=k+1,h=1; while (h!=0){ if (a[j]==')')h--; if (!h)break; if (a[j]>='A'&&a[j]<='Z'){ j=ysk(j); if (a[j]=='_')j=xbk(j)+1; }else if (a[j]=='(')h++,j=kh(j); } if (a[j+1]=='_')ans+=tmp,last=tmp,j=xb(j+1); tmp=0; return j; } void sh(int k){ int j=k+1,f=0; for (;a[j]>='0'&&a[j]<='9';j++)f=f*10+a[j]-'0'; if (!f)f++; ans+=f*18; } int main(){ start(); cin>>a; for (int i=0;i<a.size();i++){ if (a[i]>='A'&&a[i]<='Z')i=ys(i)-1; else if (a[i]=='_')i=xb(i); else if (a[i]=='(')i=kh(i); else if (a[i]=='~'){sh(i);break;} } printf ("%g",ans); return 0; }
|