转载自:https://blog.csdn.net/richenyunqi/article/details/104147851

题目描述


算法设计

利用unordered_map<string, int> ans存储整个化学方程式中出现的原子及其对应个数。
先按=将整个方程式分成两部分。左部分所有原子默认基本系数为1,右部分所有原子默认基本系数为-1。每部分最终的原子个数要乘上这个基本系数,这样处理完整个方程式中所有原子,如果配平成功所有原子对应个数应该均为0;否则有原子个数不为0 。
对于按=将分成的两部分,再按+分成多个化学式。针对每个化学式统计每种原子出现的个数。那么如何处理带()的化学式呢?我们可以采取递归处理的方法,针对遇到的每个(,找出其对应的)的位置,递归处理该()内的化学式,注意此时该()内的系数要乘上该()后紧邻的数字。找出(对应的)的方法是,设立一个变量num,初始化为1,遍历(之后的所有字符,遇到一个(就让num加1,遇到一个)num减1,那么使num==0)字符即为(对应的)


c++代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <bits/stdc++.h>
using namespace std;
int n;
string formula;
unordered_map<string, int> ans;
//返回formula的[first,last]区间对应的数字,注意函数返回之后传递给first的实参将移动到第一个非数字字符的位置
int computeDigit(int& first, int last) {
int i = 0;
for (; first <= last and isdigit(formula[first]); ++first)
i = i * 10 + formula[first] - '0';
return i == 0 ? 1 : i;
}
void f(int first, int last, int e) { //计算formula的[first,last]区间的原子及其对应系数,基本系数为e
if (first == last or (last - first == 1 and islower(formula[last]))) { //化学式是单个原子
ans[formula.substr(first, last - first + 1)] += e; //该原子个数递增e
return;
}
e *= computeDigit(first, last); //该化学式内所有原子基本系数要乘上该化学式起始系数
for (int i = first, j = i + 1; i <= last; i = j, ++j) { //遍历化学式
if (isupper(formula[i])) { //是原子
if (j <= last and 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) { //找到对应的)位置存储在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 or j > last)
j = last + 1;
f(i, j - 1, e);
}
}
int main() {
cin >> n;
while (n--) {
cin >> formula;
ans.clear();
int k = formula.find('='); //按=将方程式分割成两部分
expression(0, k - 1, 1);
expression(k + 1, formula.size() - 1, -1);
//查找有没有原子对应个数不为0
auto i = find_if(ans.begin(), ans.end(), [](const pair<string, int>& p) { return p.second != 0; });
cout << ((i == ans.end()) ? "Y" : "N") << "\n";
}
return 0;
}