201912-3 化学方程式

他这个好像之和大写字母有关系;

小写字母跟着前面的的大写字母;

+和=代表要处理了;

()代表要乘了;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring> 
#include<vector>
#include<set>
#include<stack>
using namespace std;
typedef long long ll;
const int N=3e5+10,mod=998244353;
char c[N]="+";//前面不用特判了; 后面后向加不了。。加了时候以后读入数据时好像没覆盖; 
int X[10000];

struct po{
	int a,c;
};//a相当于判断a==-1是( / ) 大于零是字母; 
vector<po>s(N);//不知道栈可不可以索引。。。。 
int hh=-1;
stack<int>st;//括号序列的处理; 

bool isdig(char x){return x>='0'&&x<='9';}
bool islow(char x){return x>='a'&&x<='z';}
bool isbig(char x){return x>='A'&&x<='Z';}

void CLEAR(int h,int K)
{
	while(hh>=0){
		int a=s[hh].a,c=s[hh].c;
		hh--;
		if(a==-1)continue;
		X[a]+=h*c*K;
	}
	return ;
}
int main()
{
    int t;
    scanf("%d",&t);
	while(t--)
	{
		scanf("%s",c+1);
		int h=1,K=1;//h是等号左边还是右边;k是每个化学式的系数; 
		for(int i=0;c[i];i++)
		{
			char x=c[i];
			if(x=='=')CLEAR(h,K),h=-1,K=1;
			else if(x=='+')CLEAR(h,K),K=1;
			else if(x=='(')s[++hh]={-1,0},st.push(hh);
			else if(x==')')s[++hh]={-1,st.top()},st.pop();//这样找到每个括号左边的位置 放到c 
			else if(isbig(x))s[++hh]={x-'A'+1,1};//+1是防止 Ag=Au 个数默认为1; 
			else if(islow(x))s[hh].a=s[hh].a*30+x-'a'+1; //小写字母就跟在之前大写字母的后面; 
			else if(isdig(x))
			{
				int v=0;
				bool H=(c[i-1]=='+'||c[i-1]=='=');//是分界限 
				while(isdig(c[i]))v=v*10+c[i]-'0',i++;
				i--;
				if(H){K=v;continue;}//赋系数; 
				if(s[hh].a==-1)
				{
					int l=s[hh].c,r=hh;
					for(int i=l;i<=r;i++)
						if(s[i].a!=-1)s[i].c*=v;//乘到里面; 
				}
				s[hh].c=v; // 修改个数; 
			}
		}
		CLEAR(h,K); 
		bool flag=1;
		for(int i=0;i<1000;i++)if(X[i])flag=0;
		puts(flag?"Y":"N");
		memset(X,0,1000*sizeof(int));
	} 
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李昌荣。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值