很经典的大模拟题目 但是还不算难 大模拟题最需要注意的就是细节
写代码一定要考虑全面 并且要细心多debug 多打断点+STL库的熟练使用
istringstream真的处理字符串非常好用
注意解耦合思想 这样改代码debug更加清晰
https://www.acwing.com/problem/content/5724/
#include<bits/stdc++.h>
using namespace std;
#define THRESHOLD 1e-5 // 设置阈值为 1e-5
//给定方程式 思考是否可以配平0
//使用矩阵 元素个数*化合物个数
int n;
//得到化学反应方程式
vector<vector<int>> get_matrix(istringstream& iss) {
map<int, map<string,int>> elements;//elements[数字][元素]=第几个化合物的元素的个数
set<string> ee;//元素个数
int m;//化合物个数
iss >> m;//化合物个数
for (int i = 0; i < m; i++) {
string material;//每一个化合物
iss >> material;
string ss;//暂存元素
for (int j = 0; j < material.size(); j++) {
if (material[j] >= 'a' && material[j] <= 'z') {
ss += material[j];
}
else {
//是数字
int num = material[j] - '0';
while ((j + 1) < material.size() && material[j + 1] >= '0' && material[j + 1] <= '9') {
num = num * 10 + (material[j + 1] - '0');
j++;
}
elements[i][ss] += num;
ee.insert(ss);
ss = "";
}
}
}
//给元素排序
vector<string> eee = vector<string>(ee.begin(), ee.end());
//元素个数*化合物个数
vector<vector<int>> matrix(eee.size(), vector<int>(m, 0));
for (int i = 0; i < ee.size(); i++) {
for (int j = 0; j < m; j++) {
matrix[i][j] = elements[j][eee[i]];
}
}
return matrix;
}
vector<vector<double>> get_gauss_matrix(vector<vector<int>> matrix) {
vector<vector<double>> double_matrix;
for (const auto& row : matrix) {
vector<double> new_row;
for (int val : row) {
new_row.push_back(static_cast<double>(val));
}
double_matrix.push_back(new_row);
}
int i = 0, j = 0;//(i,j)代表 当前矩阵左上角起始位置
while (i < double_matrix.size() && j < double_matrix[0].size()) {
int flag = 1;
for (int k = i; k < double_matrix.size(); k++) {
if (double_matrix[k][j] != 0) {
flag = 0;
break;
}
}
//对子矩阵进行重复
if (flag == 1) { j++; continue; }
//否则
else {
if (double_matrix[i][j] == 0) {
for (int k = i + 1; k < double_matrix.size(); k++) {
if (double_matrix[k][j] != 0) {
swap(double_matrix[i], double_matrix[k]);
break;
}
}
//pprint(double_matrix); cout << endl;
}
//遍历剩下所有行
for (int k = i + 1; k < double_matrix.size(); k++) {
double mul = double_matrix[k][j] / double_matrix[i][j];
for (int z = j; z < double_matrix[0].size(); z++) {
double_matrix[k][z] -= mul * double_matrix[i][z];
}
}
}
i++; j++;
// 遍历矩阵并将小于阈值的元素设为0
for (int i = 0; i < double_matrix.size(); ++i) {
for (int j = 0; j < double_matrix[0].size(); ++j) {
if (abs(double_matrix[i][j]) < THRESHOLD) {
double_matrix[i][j] = 0;
}
}
}
}
return double_matrix;
}
string judge(vector<vector<double>> gauss_matrix) {
int num = gauss_matrix[0].size();//变量个数;
int rank = 0;
int flag = 1;
for (int i = 0; i < gauss_matrix.size(); i++) {
for (int j = 0; j < gauss_matrix[i].size(); j++) {
//如果有非0的flag变成0
if (gauss_matrix[i][j] != 0) {
flag = 0;
break;
}
}
if (flag == 1) {
break;
}else {
rank++;
flag = 1;
}
}
if (rank < num) return "Y";
return "N";
}
string solve(istringstream &iss) {
vector<vector<int>> matrix=get_matrix(iss);//化学反应方程式
vector<vector<double>> gauss_matrix = get_gauss_matrix(matrix);//获得高斯消元的行阶梯形式
return judge(gauss_matrix);
}
int main() {
cin >> n;
cin.ignore(); // 忽略换行符
while (n--) {
string s;
getline(cin, s);
istringstream iss(s);
cout << solve(iss)<<endl;
}
return 0;
}