题意:给一个化学方程式,验证是否配平。
做法:
首先我们把等式两边的每一项带系数的化学式都分开,比如H2+O2=2H2O 先拆分成H2 、O2、2H2O
上边拆好的我们再把系数分离出来,处理单个的化学式比如,2H2O拆分成2 、 H2O 处理H2O
将刚刚拆出来的H2O,数据信息统计到cnt数组
1. 如果是元素后边直接跟着的数字,我们把这个数字直接给到元素的第一个字母 比如H2CO3 那么 cnt[0] = 2 ,cnt[2]=1,cnt[3] = 3
2. 如果是带括号的,比如(PO4)3那么 我们用一个栈来维护,4我们按上述步骤处理,这个括号外的3要给到“(”对应的位置。
统计好cnt数组后,我们就可以开始统计了,如果碰到的是左括号,那么要乘上相应的cnt,如果碰到的是右括号就要除以相应的cnt
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll MAXN = 1e5+5;
char a[MAXN];
map<string,int>mp1,mp2;
string s;
int cnt[505];
int len;
bool is_litte(char k){
if(k>='a' && k<='z')return 1;
else return 0;
}
bool is_big(char k){
if(k>='A' && k<='Z')return 1;
else return 0;
}
void jishu(string k){ // 计算cnt数组
//cout<<k<<endl;
int sz = k.size();
stack<int>st;
int idx=0,nb = 0;
for(int i=0;i<=sz;i++){
if(i==sz || is_big(k[i]) || k[i] == ')'){
cnt[idx] = (nb==0)?1:nb;
//cout<<idx<<" *"<<nb<<endl;
nb = 0;
idx = i;
if(i == sz)break;
if(i+1<sz && k[i+1]>='a' && k[i+1]<='z'){
i++;
}
}
if(k[i] == '('){
st.push(i);
continue;
}
if(k[i] == ')'){
int kk = st.top();
st.pop();
idx = kk;
cnt[i] = kk;
}
if (k[i]>='0' && k[i]<='9'){
nb = nb*10 +(k[i]-'0');
}
}
for(int i=0;i<sz;i++){
// cout<<cnt[i]<<" - ";
}
//cout<<endl;
}
void hua(string k,bool f){// 分离系数并且计算结果
memset(cnt,0,sizeof(cnt));
int xi = 0,idx;
for(int i=0;i<k.size();i++){
if(k[i]>='0' && k[i]<='9')
xi = xi*10 + (k[i]-'0');
else {
idx = i;break;
}
}
if(xi == 0)xi = 1;
string hua2 = k.substr(idx,k.size()-idx);
jishu(hua2);
int sz = hua2.size();
int now = 1;
string kk = "";
for(int i=0;i<sz;i++){
int chu ;
if(is_big(hua2[i])){
chu= cnt[i];
now *= cnt[i];
kk += hua2[i];
//cout<<now<<" + ";
if(i+1 < sz && is_litte(hua2[i+1])){
i++;
kk += hua2[i];
}
if(!f){
mp1[kk] += now*xi;
}
else mp2[kk] += now*xi;//,cout<<kk<<" -> "<<now*xi<<endl;
kk = "";
now /= chu;
}
if(hua2[i] == '(')now *= cnt[i];
if(hua2[i] == ')')now /= cnt[cnt[i]];
}
// cout<<endl;
}
bool fun(){ // 提取化学式
string k = "";
bool f = 0;
for(int i=0;i<=len;i++){
if(i == len || s[i] == '+' || s[i] == '='){
hua(k,f);
if(i == len)break;
if(s[i] == '=')f = 1;
k = "";
}
else k += s[i];
}
bool flag = 1;
for(auto x:mp1){
string idx = x.first;
int val = x.second;
// cout<<idx<<" --> "<<val<<endl;
if(mp2[idx]!=val)flag = 0;;
}
for(auto x:mp2){
string idx = x.first;
int val = x.second;
// cout<<idx<<" <-- "<<val<<endl;
if(mp1[idx]!=val)flag = 0;
}
return flag;
}
int main()
{
int t;
cin>>t;
while(t--){
cin>>s;
len = s.size();
mp1.clear();
mp2.clear();
if(fun()){
cout<<"Y"<<endl;
}
else cout<<"N"<<endl;
}
}
/*
11
H2+O2=H2O
2H2+O2=2H2O
H2+Cl2=2NaCl
H2+Cl2=2HCl
CH4+2O2=CO2+2H2O
CaCl2+2AgNO3=Ca(NO3)2+2AgCl
3Ba(OH)2+2H3PO4=6H2O+Ba3(PO4)2
3Ba(OH)2+2H3PO4=Ba3(PO4)2+6H2O
4Zn+10HNO3=4Zn(NO3)2+NH4NO3+3H2O
4Au+8NaCN+2H2O+O2=4Na(Au(CN)2)+4NaOH
Cu+As=Cs+Au
*/