第八届河南省程序设计大赛~~挑战密室 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还记得墙上各化学方程式用到的化学元素的原子量如下:

 

N

C

O

Cl

S

H

Al

Ca

Zn

Na

14

12

16

35

32

2

27

40

65

23

 

你能帮Dr. Kong尽快找到密码吗?

输入
第一行: K,表示有K个化学方程式;
接下来有K行,每行为一个化学方程式

输出
对于每个化学方程式输出一行:即密码。
样例输入
3
2C+O2=2CO2
NaOH+H2SO4=Na2SO4+2H2O
Ca2CO3+H2O=Ca2(OH)2+CO2
样例输出
0056
0142
0116
提示
2≤K≤8 ,化学方程式的长度不超过50, 所有原子,分子的数量不超过9.小括号最多一层.
来源
第八届河南省程序设计大赛
解题思路: 字符串处理,看到提示,这道题的难度就小很多,对于每一个化学元素 ,我们只需最多判断前三字符即可,

首先判断是不是化学元素,由题目可知,化学元素最多两个字符,我们用两个字符判断(将在代码中体现),最后再判断

化学元素后面有没有数字。详情请看代码
代码如下:
# include<stdio.h>
# include<string.h>
# include<string>
# include<iostream>
using namespace std;
char a[100],num,len;
int find(string s)
{
	if(s=="N")  return 14;
	if(s=="C")  return 12;
	if(s=="O")  return 16;
	if(s=="Cl")  return 35;
	if(s=="S")  return 32;
	if(s=="H")  return 2;
	if(s=="Al")  return 27;
	if(s=="Ca")  return 40;
	if(s=="Zn")  return 65;
	if(s=="Na")  return 23;
	return 0;
}
void count(char a[],int &i) //计算每一个化学元素的分子质量 
{	num=0;
	string s;
	s+=a[i];
	s+=a[i+1];
	if(find(s)==0) //判断化学元素是不是 两个字符 
	{
		s.clear();
		s+=a[i];
		num=find(s);
		i++;
	}
	else{
			num=find(s);     //如果是 
			i+=2;
		}
	if(i<len&&a[i]>'0'&&a[i]<='9') //判断化学元素后有没有数字 
	{
		num=num*(a[i]-'0');
		i++;
	}
}
int main(){
	int t;
	scanf("%d",&t);
	getchar();
	while(t--)
	{
		gets(a);
		int sum=0;
		len=strlen(a);
		int i=0;
		while(a[i]!='='&&i<len)
		i++;
		i++;
		int k=1;
		if(a[i]<='9'&&a[i]>'0')
		{
			k=a[i]-'0';
			i++;
		}
		while(a[i]!='+'&&i<len)
		{  
		if(a[i]!='(')	
			{
			count(a,i);	 //计算 
			}
			else 
			{	i++;
			int num1=0;
				while(a[i]!=')') //因为只有单层的括号 
				{
				count(a,i);	 //计算 
				num1+=num;					
				}				
				i++;
				if(a[i]>'0'&&a[i]<='9')  //判断括号后有没有数字 
				num=num1*(a[i]-'0');								
			}
			sum+=num;
		}
		sum*=k;
		int m=sum,l=0;
		while(m>0) //判断密码长度 
		{
			l++;
			m/=10;
		}
		for(int j=0;j<4-l;j++)
		printf("0");
		printf("%d\n",sum);
	}
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值