挑战密室
时间限制:1000 ms | 内存限制:65535 KB
难度:4
描述
R组织的特工Dr. Kong 为了寻找丢失的超体元素,不幸陷入WTO密室。Dr. Kong必须尽快找到解锁密码逃离,否则几分钟之后,WTO密室即将爆炸。
Dr. Kong发现密室的墙上写了许多化学方程式中。化学方程式,也称为化学反应方程式,是用化学式表示物质化学反应的式子。化学方程式反映的是客观事实。因此书写化学方程式要遵守两个原则:一是必须以客观事实为基础;二是要遵守质量守恒定律。
化学方程式不仅表明了反应物、生成物和反应条件。同时,化学计量数代表了各反应物、生成物物质的量关系,通过相对分子质量或相对原子质量还可以表示各物质之间的质量关系,即各物质之间的质量比。对于气体反应物、生成物,还可以直接通过化学计量数得出体积比。例如:2NaOH+H2SO4=Na2SO4+2H2O
经过多次试探、推理,Dr. Kong发现密码是4位数字,就隐藏在化学方程式等号后的第一个分子中,其分子量就可能是密码(若分子量不足4位,前面加0)。
好在Dr. Kong还记得墙上各化学方程式用到的化学元素的原子量如下:
你能帮Dr. Kong尽快找到密码吗?
输入
第一行: K,表示有K个化学方程式;
接下来有K行,每行为一个化学方程式
输出
对于每个化学方程式输出一行:即密码。
样例输入
3
2C+O2=2CO
2NaOH+H2SO4=Na2SO4+2H2O
Ca2CO3+H2O=Ca2(OH)2+CO2
样例输出
0056
0142
0116
提示
2≤K≤8 ,化学方程式的长度不超过50, 所有原子,分子的数量不超过9.小括号最多一层.
来源
第八届河南省程序设计大赛
上传者
hnu_acm
题目的意思简单明了,就是让你算出来等式右边的第一个化学分子式的相对原子质量。
我的做法是先把这个数组改变,只存在分子式。然后对它进行判断处理,有些方面用了算是一些小技巧。注意判断“(”“)”,之前没有看到括号,滞留了好久。
想了一天,好忧桑。
下面是代码:
#include<bits/stdc++.h>
using namespace std;
char s[60];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(s,0,sizeof(s));
scanf("%s",s);
int n=1,a=60,flag=0,l=strlen(s);
for(int i=0; i<l; i++)
if(s[i]=='=')
{
if(s[i+1]>='2'&&s[i+1]<='9')
{
a=i+2;
n=s[i+1]-'0';//如果分子式前有数字的话,先把数字存下来;
}
else
a=i+1;//a 标记的是分子式第一个不为数字的位置;
break;
}
int c=a;//c是等号分子式第一个不为数字的位置;
for(int i=0; i<l; i++)
{
if(s[a]=='+')
a=l;
if(i>=l-c)//如果j大于分子式的长度,数组归零;
s[i]=0;
else
s[i]=s[a++];//把数组中等号后的第一个分子式放在前边。
}
// puts(s);//尝试输出;
l=0;
for(int i=0; s[i]!=0; i++)
l++;//将l重新更新为分子式的长度
// printf("%d\n",l);//输出尝试;
int sum1=0,fla=1,sum2=0;
for(int i=0; i<l ;)
{
if(s[i]=='(')// 判断‘(’,sum2存sum1,sum1归零并且记录括号中的相对分子质量;
{
sum2=sum1;
sum1=0;
i++;
continue;
}
if(s[i]==')')//判断‘)’,并且括号后一位是否为数字,sum1更新为所有的相对分子质量;
{
if(s[i+1]>='0'&&s[i+1]<='9')
{
fla=s[i+1]-'0';
i+=2;
}
else
i++;
sum1=fla*sum1+sum2;
continue;
}
//开始判断元素,记录相对分子质量。
if( s[i]=='C')//以‘C’开头的元素,有三个,Cl,Ca,C;
{
if(s[i+1]=='l')
{
if(s[i+2]>='2'&&s[i+2]<='9')
{
sum1+=35*(s[i+2]-'0');
i+=3;
}
else
{
sum1+=35;
i+=2;
}
}
else if(s[i+1]=='a')
{
if(s[i+2]>='2'&&s[i+2]<='9')
{
sum1+=40*(s[i+2]-'0');
i+=3;
}
else
{
sum1+=40;
i+=2;
}
}
else
{
if(s[i+1]>='2'&&s[i+1]<='9')
{
sum1+=12*(s[i+1]-'0');
i+=2;
}
else
{
sum1+=12;
i++;
}
}
}
else if(s[i]=='N')// 以N开头的元素有两个, Na,N;
{
if(s[i+1]=='a')
{
if(s[i+2]>='2'&&s[i+2]<='9')
{
sum1+=23*(s[i+2]-'0');
i+=3;
}
else
{
sum1+=23;
i+=2;
}
}
else if(s[i+1]>='2'&&s[i+1]<='9')
{
sum1+=14*(s[i+1]-'0');
i+=2;
}
else
{
sum1+=14;
i++;
}
}
else if(s[i]=='O')//判断‘O’;
{
if(s[i+1]>='2'&&s[i+1]<='9')
{
sum1+=16*(s[i+1]-'0');
i+=2;
}
else
{
sum1+=16;
i++;
}
}
else if(s[i]=='S')//判断‘S’;
{
if(s[i+1]>='2'&&s[i+1]<='9')
{
sum1+=32*(s[i+1]-'0');
i+=2;
}
else
{
sum1+=32;
i++;
}
}
else if(s[i]=='H')//判断‘H’;
{
if(s[i+1]>='2'&&s[i+1]<='9')
{
sum1+=2*(s[i+1]-'0');
i+=2;
}
else
{
i++;
sum1+=2;
}
}
else if(s[i]=='A'&&s[i+1]=='l')//判断‘Al’;
{
if(s[i+2]>='2'&&s[i+2]<='9')
{
sum1+=27*(s[i+2]-'0');
i+=3;
}
else
{
i+=2;
sum1+=27;
}
}
else if(s[i]=='Z'&&s[i+1]=='n')
{
if(s[i+2]>='2'&&s[i+2]<='9')
{
sum1+=65*(s[i+2]-'0');
i+=3;
}
else
{
i+=2;
sum1+=65;
}
}
}
printf("%04d\n",sum1*n);//输出的时候直接用%4d,不足的补前导零;
}
return 0;
}