高斯消元与行列式求值 part1

两道模板题,思路与算法却是相当经典。

先说最开始做的行列式求值,题目大致为给一个10*10的行列式,求其值

具体思路(一开始看到题我的思路):

1.暴算,把每种可能组合试一遍,求逆序数,做相应加减运算,一看就知道不是正解。

2.暴算2.0 用递归和代数余子式计算,但同样需计算逆序数。

3.一看就是知道是正解高斯消元,将行列式消为上三角,将对角线相乘。

看看代码:

#include<bits/stdc++.h>      //喜闻乐见的万用头
using namespace std;
int n;
double a[11][11];            //因需处理小数,开double
int t=1;
bool no;
double tim=1; //储存约去系数int main(){ cin>>n; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++) scanf("%lf",&a[i][j]); //由于数据较少(10*10),不用快读 } for(int i=1;i<=n;i++){ if(!a[i][i]){ //判断当前处理数据是否为0,point t=i; while(!a[t][i]&&t<=n) t++; if(t==n+1){no=1; continue;} //筛选首项不为0的行,进行交换,别忘记*=-1,最少wa4个 for(int j=1;j<=n;j++) swap(a[i][j],a[t][j]); tim*=-1; } double x=a[i][i]; //将该行非0首项(之前的运算保证其不为0且为第一的非0数) for(int j=i;j<=n;j++) a[i][j]/=x; //将每个a[i][i]除为1 tim*=x; //将消去系数累乘保存 for(int j=i+1;j<=n;j++){ x=a[j][i]; for(int k=1;k<=n;k++) a[j][k]-=x*a[i][k]; //将每行首项消为0,其余数做相同运算 } /*for(int j=1;j<=n;j++){ //输出看看行列式消得对不对 for(int k=1;k<=n;k++) cout<<a[j][k]<<" "; cout<<endl; }*/ } printf("%0.0lf",tim*a[n][n]); //输出系数与最后一项的乘积,取整 return 0; }
p.s.:“no”好像在这里没有用,不知为啥就写上了。。。
//以下是例题没有的特殊数据
/*8 5 5 10 9 5 9 10 4 3 3 6 1 4 6 7 10 1 1 2 10 8 9 8 7 6 2 3 4 8 3 6 9 1 2 6 3 2 7 8 9 9 5 4 5 1 7 3 10 2 4 6 10 10 5 7 8 4 5 6 10 4 7 5 2*/

point:(以后把需要较大量文字叙述的重点用文下注释解释)

如果a[i][i]为0,则在将要进行的化简运算中会出现  n/0 情况,

对于此类数字输出为“nan”(同学说这是暗示这道题难。。。)“not a number”

而对于此处出现的0,根据高斯消元的相关理论应该往下换,毕竟要组成下三角需把0“沉下去”,所以与下面换行。

p.s.:这道题给了我一点启示:

当初同学最快做出来得了11分,我初次尝试得了64分,这给了我做出来的动力,非常大的动力

我便梦想总有一天我要在全56级初学者之前a掉它,自此,我在家打开的窗口不再是虐杀原形,而是c++,为此,我改变了3次算法,代码重构好多次,提交。。。10几次是有了吧,乘积由64提到95,再提到96,最后查出致命错误终是a了,并达成了梦想。。。不总结了,只是希望以后万念俱灰的自己看到这个能。。。cheer下吧

猜你喜欢

转载自www.cnblogs.com/648-233/p/10686283.html