前言
随便在网上翻到这样一个东西。
配平以下化学方程式。
KMnO4+FeSO4+H2SO4 Fe2(SO4)3+MnSO4+K2SO4+H2O
看上去十分不可做,因此考虑是否可使用 OI 方法求通解,所以就有了这篇文章。
物理课上随便想的喵喵喵。
题目大意
给定一个如下的化学方程式,有
n+1 种反应物
X0∼n 和
m 种生成物
Xn+1∼m,下面你需要给其配平(即求出所有
ai 的值,必须为正整数)。
a0X0+a1X1+⋯+anXn an+1Xn+1+an+2Xn+2+⋯+an+mXn+m
所有
X 以一个
(n+m+1)k 的矩阵
c 给出,其中
k 表示所有
X 中的元素总种数,
ci,j 表示一个
Xi 分子中第
j 种元素有
ci,j 个原子。数据范围满足
n+m≤500。
解题思路
首先不妨令
a0=1,最后再将所有
ai 通分,这样就把正整数规约为了分数,并且可以把所有
c0,j 作为常数项。
根据质量守恒定律,不难想到对于每种元素
j 都能构成一个方程。
c0,j+i=1∑nci,jai=i=n+1∑n+mci,jai
方程化为
−c1,ja1−c2,ja2−⋯−cn,jan+cn+1,jan+1+⋯+cn+m,jan+m=c0,j
于是可以把所有
ci,j (1≤i≤n) 取反,就形成了一个普通的
n+m 元方程,这
k 个方程就构成了一个
n+m 元线性方程组。
⎩⎨⎧c1,1a1+c2,1a2+⋯+cn+m,1an+m=c0,1,c1,2a1+c2,2a2+⋯+cn+m,2an+m=c0,2,⋯c1,ka1+c2,ka2+⋯+cn+m,kan+m=c0,k
直接高斯消元求解即可。此时求得的
ai 都是分数的形式,所以所有
ai 乘上
lcm(a1∼n) 即可,理论时间复杂度
O[(n+m)3]。
下面以前言中的题目为例。依题意得
c=00−20002(H)4−4−412441(O)0−1−13110(S)1000020(K)1000100(Mn)0−102000(Fe)(KMnO4)(FeSO4)(H2SO4)[Fe2(SO4)3](MnSO4)(K2SO4)(H2O)
高斯消元得
a={1,5,4,25,1,21,4}
通分得
a={2,10,8,5,2,1,8}
所以最终的方程式为
2KMnO4+10FeSO4+8H2SO45Fe2(SO4)3+2MnSO4+K2SO4+8H2O
AC 代码
懒得写了()反正大力高斯消元加一个分数类应该就能很好实现了,期待有人写出来 std 发我。
课后作业
配平以下化学方程式。
H2+Ca(CN)2+NaAlF4+FeSO4+MgSiO3+KI+H3PO4+PbCrO4+BrCl+CF2Cl2+SO2 PbBr2+CrCl3+MgCO3+KAl(OH)4+Fe(SCN)3+PI3+Na2SiO3+CaF2+H2O