题目描述
AC鸭最近开始对化学方程式感兴趣了,他每天钻研25小时的化学方程式,现在“荣幸”的被选为了化学课代表,成为化学课代表后,它有了一个至高无上的权利:帮助检查其他同学的化学完成情况,所有的化学都由化学方程式组成,他的任务就是检查化学方程式是否平衡,化学方程式是一种使用符号和公式来表示化学反应的方法,在化学反应中,一组初始分子发生反应以产生另一组新的分子。
一个化学方程式分为左右两边,左边是初始分子的化学式,右边为产物分子的化学式。等式两边由 -> 分隔,在左边或者右边的不同分子用+分隔。分子是由原子构成,如果一个分子具有多个相同原子,则该原子的出现次数写在公式中的原子之后。例如,AC4B,表示该分子具有一个原子 A、4 个原子 C 和一个原子 B。
若在方程的一侧,一个分子不止出现一次,那么这个出现的次数写在该分子式的前面,例如:3AC4B 表示 3 个 AC4B 分子,总共有 3 个原子 A、12 个原子 C 和 3 个原子 B。
如果化学方程式的右侧和左侧原子每一种原子的数量相同,且左边原子的种类数与右边原子种类数相同,则称该化学方程式是平衡的。
你的任务是确定个化学方程式中的每一个化学方程式是否平衡。
输入
输入的第一行给出一个整数一表示有 n 个化学方程式。
接下来行。每一行给出一个字符串 S 一表示一个化学方程式,注意,原子均为大写英文字母组成,分子由原子和数字组成。
1
≤
�
≤
10
1≤n≤10
�
≤
1000
S≤1000
题目保证单个化学方程式中元素的总个数在 int 范围之内。 题目保证每一个分子前面的数字是个位数,不保证其他数字是个位数
输出
输出行,对于每一个化学方程式,若平衡输出 YES,否则输出 NO。
样例
输入数据 1
7
A+B->AB
2AB+2AC+2BC->4ABC
2AB+A->3AB
2H2O+2CO2->2H2CO3
H2SO4->H2O4
NH3+H2SO4->NH4SO4
CH4+2O2->CO2+2H2O
输出数据 1
YES
YES
NO
YES
NO
NO
YES
【以下回答由 GPT 生成】
首先,我们需要根据输入数据的格式进行解析,将每个化学方程式拆分成左右两部分。
然后,我们需要对每个方程式进行平衡检查。具体的步骤如下:
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
// 检查化学方程式是否平衡
string checkBalance(const string& equation) {
// 找到等号的位置,将化学方程式分为左右两部分
int arrowPos = equation.find("->");
string leftStr = equation.substr(0, arrowPos);
string rightStr = equation.substr(arrowPos + 2);
// 统计左边和右边每种元素的数量
unordered_map<char, int> leftElements;
for (int i = 0; i < leftStr.size(); i++) {
char c = leftStr[i];
if (isalpha(c)) {
// 元素名字
char element = c;
int count = 1;
// 统计元素的数量
while (i + 1 < leftStr.size() && isdigit(leftStr[i + 1])) {
count = count * 10 + (leftStr[i + 1] - '0');
i++;
}
leftElements[element] += count;
}
}
unordered_map<char, int> rightElements;
for (int i = 0; i < rightStr.size(); i++) {
char c = rightStr[i];
if (isalpha(c)) {
// 元素名字
char element = c;
int count = 1;
// 统计元素的数量
while (i + 1 < rightStr.size() && isdigit(rightStr[i + 1])) {
count = count * 10 + (rightStr[i + 1] - '0');
i++;
}
rightElements[element] += count;
}
}
// 检查左边和右边的元素数量是否相等
if (leftElements == rightElements) {
// 检查左边和右边的元素种类数是否相等
if (leftElements.size() == rightElements.size()) {
return "YES";
}
}
return "NO";
}
int main() {
int n;
cin >> n;
cin.ignore();
for (int i = 0; i < n; i++) {
string equation;
getline(cin, equation);
string result = checkBalance(equation);
cout << result << endl;
}
return 0;
}
代码的时间复杂度为O(n*m),其中n表示化学方程式的数量,m表示每个化学方程式的长度。由于题目中给出的条件是n不超过10个,m不超过1000,所以该算法的时间复杂度是可以接受的。
【相关推荐】
供参考:
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int MAXN = 1e3 + 5;
char s[MAXN];
int a[MAXN];
bool ex(string x, int flag)
{
int cnt = 0, ret = 0, res = 0, i = 0;
for (i = 0; i < x.length(); ++i) {
if ((x[i] >= 'A' && x[i] <= 'Z') || (x[i] >= 'a' && x[i] <= 'z')) {
if ((x[i] >= 'A' && x[i] <= 'Z'))
cnt = cnt * 29 + (x[i] - 'A' + 1), ret++;
else
cnt = cnt * 29 + (x[i] - 'a' + 1);
if (ret >= 2)
return false;
}
else
break;
}
for (; i < x.length(); ++i)
if (x[i] >= '0' && x[i] <= '9')
res = res * 10 + x[i] - '0';
else
return false;
if (res)
flag *= res;
a[cnt] += flag;
return true;
}
int toint(string x)
{
string y;
int cnt = 0, i, ret = 0;
for (i = 1; i < x.length(); ++i) {
if (cnt == 0 && x[i] == ')') {
++i;
break;
}
if (x[i] == '(')cnt++;
if (x[i] == ')')cnt--;
y += x[i];
}
for (; i < x.length(); ++i)
ret = ret * 10 + x[i] - '0';
if (ret);
else ret = 1;
return ret;
}
string tostring(string x) {
string y;
int cnt = 0, i = 1, ret = 0;
for (; i < x.length(); ++i) {
if (cnt == 0 && x[i] == ')') {
++i;
break;
}
if (x[i] == '(')cnt++;
if (x[i] == ')')cnt--;
y += x[i];
}
return y;
}
void slove(string x, int flag)
{
if (ex(x, flag))
return;
int pos = 0, res = 0, cnt = 0, i = 0, j = x.length() - 1;
for (;; ++i) {
if (x[i] >= '0' && x[i] <= '9')pos = pos * 10 + x[i] - '0';
else
break;
}
if (pos)flag *= pos;
string y;
for (; i < x.length(); ++i) {
if (x[i] == '(')cnt++;
if (x[i] == ')')cnt--;
if (cnt == 0 && (i + 1 == x.length() || (x[i + 1] >= 'A' && x[i + 1] <= 'Z') || x[i + 1] == '(')) {
y += x[i];
int b = flag;
if (y[0] == '(') {
b *= toint(y);
y = tostring(y);
}
slove(y, b);
y.clear();
}
else
y += x[i];
}
}
int main() {
int T;
string t;
scanf("%d", &T);
while (T--) {
memset(a, 0, sizeof(a));
int flag = 1;
scanf("%s", s);
t.clear();
int ls = strlen(s);
for (int i = 0; i <= ls; ++i) {
if (i == ls || s[i] == '+' || s[i] == '-' || s[i] == '>') {
if (s[i] == '-') continue;
slove(t, flag);
t.clear();
if (s[i] == '>') flag = -1;
}
else
t += s[i];
}
int f = 1;
for (int i = 0; i <= 1000; ++i) {
if (a[i]) {
f = 0; break;
}
}
if (f)
cout << "YES";
else
cout << "NO";
if (T) cout << endl;
}
return 0;
}
//输入样例:
#if 0
7
A+B->AB
2AB+2AC+2BC->4ABC
2AB+A->3AB
2H2O+2CO2->2H2CO3
H2SO4->H2O4
NH3+H2SO4->NH4SO4
CH4+2O2->CO2+2H2O
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
NO
YES
NO
YES
YES
YES
YES
YES
YES
YES
NO
#endif
#include <stdio.h>
#include <string.h>
int main() {
int n;
scanf("%d", &n);
while (n--) {
char s[1000];
scanf("%s", s);
int left_count = 0, right_count = 0;
int left[26] = {0}, right[26] = {0};
int i = 0;
whilej] - '0';
j++;
}
i += j - 1;
} else {
int j = 0;
while (s[i+j] >= '0' && s[i+j] <= '9') {
right_count *= 10;
right_count += s[i+j] - '0';
j++;
}
i += j - 1;
}
i++;
}
i++;
while (s[i] != '\n') {
if (s[i] >= 'A' && s[i] <= 'Z') {
right[s[i]-'A']++;count += s[i+j] - '0';
j++;
}
i += j - 1;
}
i++;
}
if (left_count == right_count && memcmp(left, right, sizeof(left)) == 0) {
printf("YES\n");
} else {
printf("NO\n");
}
}
return 0;
}