高斯消元裸题,存为模板吧。值得注意的是精度1e-8、1e-10过不去,但是1e-6能过,据说每次找最大的行消元可以减小误差。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
#include <stack>
using namespace std;
const double eps = 1e-6; //坑!
bool Equal(double a,double b){
return (fabs(a-b)<eps);
}
int n,m;
double a[1010][1010];
double b[1010];
double ans[1010];
void Swap(int i,int j){
for(int k=1;k<=n;k++){
swap(a[i][k],a[j][k]);
}
swap(b[i],b[j]);
}
int main(){
while(cin>>n>>m){
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
cin>>b[i];
}
bool mul=0;
for(int i=1;i<=n;i++){ //处理第i列
bool flag = false;
for(int j=i;j<=m;j++){
if(!Equal(a[j][i],0.0)){ //发现第i列不为0的行j
if(i!=j)Swap(j,i); //交换ij两行
flag=1;
break;
}
}
if(!flag){ //如果找不到这样的行
mul=1;
break;
}
for(int j=i+1;j<=m;j++){ //第i+1行~m行的第i列清空
double tmp = a[j][i]/a[i][i];
for(int k=1;k<=n;k++){ //处理a[j][k]
a[j][k]-=a[i][k]*tmp;
}
//处理b[j]
b[j]-=b[i]*tmp;
}
}
bool no=0;
for(int i=1;i<=m;i++){
bool flag=0;
if(!Equal(b[i],0)){
for(int j=1;j<=n;j++){
if(!Equal(a[i][j],0))flag=1;
}
if(!flag){
no=1;
}
}
}
if(no){
printf("No solutions\n");
continue;
}
if(mul){
printf("Many solutions\n");
continue;
}
for(int i=n;i>=1;i--){
for(int j=i+1;j<=n;j++){
b[i]-=a[i][j]*ans[j];
a[i][j]=0;
}
ans[i]=b[i]/a[i][i];
}
for(int i=1;i<=n;i++){
printf("%d\n",(int)(ans[i]+eps));
}
}
return 0;
}