nyoj 1236 挑战密室

挑战密室

时间限制: 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还记得墙上各化学方程式用到的化学元素的原子量如下:

                 nyoj 1236 挑战密室_第1张图片

你能帮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.小括号最多一层.
来源
第八届河南省程序设计大赛
解题思路:这个题就是让求等号后面出现的第一个分子的相对分子质量*分子个数,得出的结果如果不满四位,则前面补0,刚开始想到的是遍历,并依次判断,写着写着发现这样的话对于原子来说处理并不好,后来果断重写,使用栈来解决;

1、当遇到一个原子时,就把该原子入栈,继续往后遍历;

2、遍历遇到数字 i 时,说明该原子有 i 个,则把栈顶的原子弹出,并计算相对质量(sum1);

3、遇到左括弧时,将左括弧入栈;

4、在遇到右括弧之前重复上述步骤 1、2,(括弧内的原子质量sum2来存)

5、遇到右括弧计算括弧内剩下的所有原子的质量

6、最后sum1+sum2 就是总的相对分质量

请参看代码中的详解,如有不明白之处,尽请留言...

具体代码:
#include 
#include 
#include 
using namespace std;
//初始化,每个原子的相对质量对应Inia数组中的数字 
char Ins[10][3]={"N","C","O","Cl","S","H","Al","Ca","Zn","Na"};
int Inia[10]={14,12,16,35,32,2,27,40,65,23};
char s[55];
struct Node
{
	char str[3];
};
stack  osta;
Node D;
int sum1=0,sum2=0;
int Find(char *str)//查找某个原子的相对质量 
{
	for(int i=0;i<10;i++)
		if(strcmp(str,Ins[i])==0)
			return Inia[i];
}
int fun(int sum,int i)
{
	if(s[i]>='A'&&s[i]<='Z' && s[i+1]>='a'&&s[i+1]<='z')
	{//是有两个字符组成的原子 
		D.str[0]=s[i],D.str[1]=s[i+1],D.str[2]='\0';
		osta.push(D);
	}
	else if(s[i]>='A'&&s[i]<='Z')
	{//单个字符组成的原子 
		D.str[0]=s[i],D.str[1]='\0';
		osta.push(D);
	}
	else if(s[i]>'0' && s[i]<='9')
	{//多个原子 
		Node p=osta.top();
		sum+=Find(p.str)*(s[i]-'0');
		osta.pop();
		return sum;
	}
	return 0;
}
int main()
{
	int T;
	char str[2];
	scanf("%d",&T);
	while(T--)
	{
		scanf("\n%s",&s);
		int flag_z=1,i=0;
		sum1=0; sum2=0;
		while(s[i++]!='=');//遍历到 = 结束
		if(s[i]>'0' && s[i]<='9')//判断等号后的第一位是不是数字,如果是的话,说明有多个分子
			flag_z=s[i++]-'0';//记录该分子有多少个 
		while(s[i]!='+' && i'0' && s[i]<='9')//说明括弧内的离子团有多个 
					sum2*=(s[i++]-'0');
			}
		}
		while(!osta.empty())
		{ //栈内剩余原子依次出栈求和 
			Node p=osta.top();
			sum1+=Find(p.str);
			osta.pop();
		}
		//分子个数*单个分子的相对分质量 
		int ans=flag_z*(sum1+sum2);
		if(ans<10)
			printf("000%d\n",ans);
		else if(ans<100)
			printf("00%d\n",ans);
		else if(ans<1000)
			printf("0%d\n",ans);
		else
			printf("%d\n",ans);
	}
	return 0;
}

你可能感兴趣的:(栈stack的应用)