Xtreme 10.0 - Counting Molecules
题目:
https://www.hackerrank.com/contests/ieeextreme-challenges/challenges/counting-molecules
题意:
输入碳(C)、氢(H)、氧(O)原子的数量,判断这些原子能否仅组成水分子(H2O)、二氧化碳分子(CO2)、葡萄糖分子(C6H12O6)。
输入:三个数C H O,用空格隔开,分别代表碳原子(C)、氢原子(H)、氧原子(O)的数量,其中 0 <= C, H, O < 10 ^ 10。
输出:如果输入的三个数仅仅能用于组成水分子(H2O)、二氧化碳分子(CO2)、葡萄糖分子(C6H12O6),则输出三种分子的数量,否则输出Error。
测试用例:
输入:10 0 20
输出:0 10 0
思路:
设H2O、CO2、C6H12O6的分子数分别为x、y、z,根据题意可以列出方程组:
(1)y + 6z = C
(2)2x + 12z = H
(3)x + 2y + 6z = O
求解出该线性方程组,只要解出的x、y、z值为整数,则说明原题有解,直接输出x y z,否则输出Error。
其中,求解线性方程组的关键步骤是求出系数矩阵的逆矩阵。
代码:
#include <iostream>
using namespace std;
const double maxErr = 0.00001;
bool isIntVal(double n) {
int intVal = (int)n;
if ((n - intVal) <= maxErr) return true;
if ((intVal + 1 - n) < maxErr) return true;
return false;
}
int integerVal(double n) {
int val = (int)n;
if ((n - val) <= maxErr) return val;
if ((val + 1 - n) <= maxErr) return val + 1;
return -1;
}
void CountingMolecules() {
long long C = 0, H = 0, O = 0;
cin >> C >> H >> O;
double mat[3][3] = {
-1.0, 1.0 / 4, 1.0 / 2,
0.0, -1.0 / 4, 1.0 / 2,
1.0 / 6, 1.0 / 24, -1.0 / 12
};
bool canSlove = true;
double H2O = C * mat[0][0] + H * mat[0][1] + O * mat[0][2];
double CO2 = C * mat[1][0] + H * mat[1][1] + O * mat[1][2];
double C6H12O6 = C * mat[2][0] + H * mat[2][1] + O * mat[2][2];
if (!isIntVal(CO2) || !isIntVal(H2O) || !isIntVal(C6H12O6)) {
cout << "Error" << endl;
return;
}
cout << integerVal(H2O) << ' ' << integerVal(CO2) << ' ' << integerVal(C6H12O6) << endl;
return;
}
int main() {
CountingMolecules();
}