化学方程式 CCF-CSP认证201912

这篇博客详细介绍了作者在处理一个C++编程任务时,针对化学方程式进行预处理、递归下降法解析以及验证的过程。通过建立结构体和映射来存储和操作字符串,实现了对化学方程式左右两边原子数量的比较,以判断方程式是否成立。主要涉及C++的数据结构、字符串处理和算法应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://118.190.20.162/view.page?gpid=T98

这题搞了差不多快两个小时

然后第4,5题直接GG,身败名裂

预处理系数,递归下降法

// INFO BEGIN
//
// User = 201911507842(刘峰玮) 
// Group = C/C++ 
// Problem = 化学方程式 
// Language = CPP11 
// SubmitTime = 2019-12-15 15:21:46 
//
// INFO END

#include<bits/stdc++.h>
using namespace std;

const int maxl=1e4+10;

int n,ans,tot1,tot2,top,zz;
map<string,int> mp1,mp2;
struct node
{
	int l,r;
}a1[maxl],a2[maxl];
int res[maxl],pre[maxl],nxt[maxl],stk[maxl];
char s[maxl];

inline void prework()
{
	scanf("%s",s+1);
	n=strlen(s+1);
	mp1.clear();mp2.clear();
	string ds;
	top=0;
	for(int i=1;i<=n;i++)
	if(s[i]=='(')
		stk[++top]=i;
	else if(s[i]==')')
		pre[i]=stk[top],nxt[stk[top]]=i,top--;
	else if(s[i]=='=')
		zz=i;
	int l=1;tot1=0;tot2=0;
	for(int i=1;i<zz;i++)
	if(s[i]=='+')
	{
		++tot1;
		a1[tot1].l=l,a1[tot1].r=i-1;
		l=i+1;
	}
	++tot1;a1[tot1].l=l,a1[tot1].r=zz-1;
	l=zz+1;
	for(int i=zz+1;i<=n;i++)
	if(s[i]=='+')
	{
		++tot2;
		a2[tot2].l=l;a2[tot2].r=i-1;
		l=i+1;
	}
	++tot2;a2[tot2].l=l;a2[tot2].r=n;							///
}

inline map<string,int> find(int l,int r)
{
	map<string,int> ret,t;ret.clear();
	int xishu=1;
	if(s[l]>='0' && s[l]<='9')
	{
		xishu=0;
		while(s[l]>='0' && s[l]<='9')
			xishu=xishu*10+s[l]-'0',l++;
		ret=find(l,r);
		for(auto d : ret)
			ret[d.first]*=xishu;
		return ret;
	}
	string ds;
	for(int i=l;i<=r;i++)
	{
		t.clear();
		if(s[i]=='(')
		{
			t=find(i+1,nxt[i]-1);
			i=nxt[i];
		}
		else
		{
			ds=s[i];
			if(s[i+1]>='a' && s[i+1]<='z')
			{
				i++;
				ds+=s[i];
			}
			t[ds]=1;
		}
		if(i+1>r || !(s[i+1]>='0' && s[i+1]<='9'))
			xishu=1;
		else
		{
			xishu=0;
			while(i<r && s[i+1]>='0' && s[i+1]<='9')
				xishu=xishu*10+s[i+1]-'0',i++;
		}
		for(auto d : t)
			ret[d.first]+=xishu*d.second;
	}
}

inline void mainwork()
{
	map<string,int> t;
	for(int i=1;i<=tot1;i++)
	{
		t=find(a1[i].l,a1[i].r);
		for(auto d : t)
		{
			//cout<<d.first<<" "<<d.second<<"\n";
			mp1[d.first]+=d.second;
		}
	}
	for(int i=1;i<=tot2;i++)
	{
		t=find(a2[i].l,a2[i].r);
		for(auto d: t)
		{
			//cout<<d.first<<" "<<d.second<<"\n";
			mp2[d.first]+=d.second;
		}
	}
	ans=1;
	for(auto d : mp1)
	if(mp2[d.first]!=d.second)
		ans=0;
	for(auto d : mp2)
	if(mp1[d.first]!=d.second)
		ans=0;
}

inline void print()
{
	if(ans)
		printf("Y");
	else
		printf("N");
}

int main()
{
	int t;
	scanf("%d",&t);
	for(int i=1;i<=t;i++)
	{
		prework();
		mainwork();
		print();
		if(i<t)
			puts("");
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值