题目描述
C++代码
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
/*
利用unordered_map<string, int> ans存储整个化学方程式中出现的原子及其对应个数。
先按=将整个方程式分成两部分。左部分所有原子默认基本系数为1,右部分所有原子默认基本系数为-1。每部分最终的原子个数要乘上这个基本系数,这样处理完整个方程式中所有原子,如果配平成功所有原子对应个数应该均为0;否则有原子个数不为0 。
对于按=将分成的两部分,再按+分成多个化学式。针对每个化学式统计每种原子出现的个数。那么如何处理带()的化学式呢?我们可以采取递归处理的方法,针对遇到的每个(,找出其对应的)的位置,递归处理该()内的化学式,注意此时该()内的系数要乘上该()后紧邻的数字。找出(对应的)的方法是,设立一个变量num,初始化为1,遍历(之后的所有字符,遇到一个(就让num加1,遇到一个)让num减1,那么使num==0的)字符即为(对应的)。
*/
int n;
string formula;
unordered_map<string, int>ans;
int computeDigit(int first, int last)
{
int i = 0;
for (; first <= last&&isdigit(formula[first]); first++)
{
i = i * 10 + formula[first] - '0';
}
return i == 0 ? 1 : i;
}
void f(int first, int last, int e)//计算formula的[f,l]区间的原子及对应系数 这是一个+分割的
{
if (first == last || last - first == 1 && islower(formula[last]))
{
ans[formula.substr(first, last - first + 1)] += e;
return;
}
//2nacl 先让e * 最前面的数
e *= computeDigit(first, last);
for (int i = first, j = i + 1; i <= last; i = j, ++j)//遍历化学式
{
if (isupper(formula[i]))//一般原子是2个字符或1个 NaOH
{
if (j <= last&&islower(formula[j]))//后面是小写
++j;
int k = j;
f(i, k - 1, e*computeDigit(j, last));//第三个参数思考一下
}
else if (formula[i] == '(')
{
for (int num = 1; num != 0; ++j)
{
if (formula[j] == '(')
++num;
else if (formula[j] == ')')
--num;
}
int k = j;
f(i + 1, k - 1, e*computeDigit(j, last));
}
}
}
void expression(int first, int last, int e)//按+分离出所有化学式
{
for (int i = first,j=first; i <= last; i=j+1)
{
j = formula.find('+', i);
if (j == string::npos || j > last)
j = last + 1;
f(i, j - 1, e);//可能没有加号 然后直接找到最后
}
}
int main()
{
scanf("%d", &n);
getchar();
while (n--)
{
getline(cin, formula);
ans.clear();//必须clear
int k = formula.find('=');
expression(0, k - 1, 1);
expression(k + 1, formula.size() - 1, -1);
int flag = 1;
for (unordered_map<string, int> ::iterator it = ans.begin(); it != ans.end(); it++)
{
if (it->second != 0)
{
flag = 0;
break;
}
}
if (flag)
printf("Y\n");
else
printf("N\n");
}
return 0;
}
/*
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
*/