题目
思路
化学方程式是需要配平的,就是等式两边相同元素个数一致,在这样的情况下可以使用map<string,int>,string代表元素,int代表个数,我们可以假令左侧为正,右侧为负,这样只需要最后结果为0就行,如果不是0,说明没有配平,还有一个点就是要以‘+’为分割,分出各个化学式,面对括号嵌套的情况可以进行递归求解,在处理的时候还要注意系数。
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long int
map<string,int> m;
ll compute(string s,ll x) {
ll num = 0;
while(x < s.size() && isdigit(s[x])) {
num *= 10;
num += s[x] - '0';
x++;
}
if(!num) {
return 1;
}
else{
return num;
}
}
void deal(string s,ll exp) {
ll i = 0, j;
exp *= compute(s, i);
while(i < s.size()) {
if(isdigit(s[i])) {
i++;
continue;
}
if(isupper(s[i])) {
if(i + 1 < s.size() && islower(s[i+1])) {
ll k = i;
i += 2;
m[s.substr(k, 2)] += exp * compute(s,i);
}
else{
ll k = i;
i += 1;
m[s.substr(k, 1)] += exp * compute(s, i);
}
}
else{
ll left = i, right = i + 1, num = 1;
while(num != 0 && right < s.size()) {
if(s[right] == '(') {
num++;
}
else if(s[right] == ')') {
num--;
}
right++;
}
deal(s.substr(left + 1, right - left - 2), exp * compute(s, right));
i = right;
}
}
}
void solve(string s,ll x) {
ll i, j;
for(i = 0; i < s.size();) {
j = s.find('+', i);
//只有一个式子
if(j == -1) {
deal(s.substr(i),x);
i = s.size();
}
//不只有一个式子
else{
deal(s.substr(i, j - i),x);
i = j + 1;
}
}
}
int main()
{
int n;
cin >> n;
while (n--) {
string s;
cin >> s;
m.clear();
int pos;
pos = s.find('=');
if(pos == -1) {
cout << "N" << endl;
continue;
}
solve(s.substr(0,pos),1);
solve(s.substr(pos+1),-1);
map<string,int>::iterator it = m.begin();
bool flag = false;
for(;it != m.end(); it++) {
if((*it).second != 0) {
cout << "N" << endl;
flag = true;
break;
}
}
if(flag) {
continue;
}
cout << "Y" << endl;
}
return 0;
}