原題連結:https://www.acwing.com/activity/content/11

敲代碼的注意事項:
1.for循環中的”++”和”- -“符号要應情況而選擇,否則及容易打錯,進而出現一些非常難找到的bug
2.doule和int的類型需要注意,例如輸入輸出過程,和定義過程
3.return的類型
代碼:
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=110;
const double egs=1e-6;
double a[N][N];
int n;
int gause()
{
int r,c;//r表示目前所在的行數,c表示目前所指向的列數
for(r=0,c=0;c<n;c++)//進行n次循環,将矩陣化為三角的形式
{
int t=r;
for(int i=r;i<n;i++)
if(fabs(a[t][c])<fabs(a[i][c]))
t=i;
//尋找最大的數值是因為可以避免系數變得太大,精度較高.
if(fabs(a[t][c])<egs) continue;//如果最大值是零,便可以直接跳過了
//之是以要小于1e-6,是因為c++浮點數的一種弊端,是以小于egs時,可以近似的看作是0
for(int i=c;i<=n;i++) swap(a[t][i],a[r][i]);
//尋找到之後進行交換操作
for(int i=n;i>=c;i--) a[r][i]/=a[r][c];
//将目前第c位的值初始化為1,當然其他數也同樣需要除以第c位,之是以從第n位開始,是為了不覆寫掉第c位的值
for(int i=r+1;i<n;i++)
if(fabs(a[i][c])>egs)//如果目前行數為零,說明不用進行削為零的操作
for(int j=n;j>=c;j--)
a[i][j]-=a[i][c]*a[r][j];
r++;
}
if(r<n)
{
for(int i=r;i<n;i++)
if(a[i][n]>egs)
return 2;//無解
/*
如果目前列的絕對值最大的值是0,那麼r還繼續停留,不轉到下一行,但c卻轉至下一行,
由于循環過程中會進行消元操作,是以循環到該列時,下面所有行的c列就會被消成零.
假設該列隻有零的情況出現一次的話,那麼r最終會循環到n-2行,而c卻循環到了第n-1列,
因為循環過程中的消元,是以第n-1行的所有數都會被消成零.如果此時d不為零的話,沖突,無解;
如果為零的話,那麼就會有無數組解.一列都是零的情況出現兩次,三次,甚至更多次都是同理.
*/
return 1;//無數解
}
//将未知數求解出來
for(int i=n-1;i>=0;i--)//i,j表示'行'的同時也表示'列'
for(int j=i+1;j<n;j++)
a[i][n]-=a[j][n]*a[i][j];
return 0;//有唯一解
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<=n;j++)
scanf("%lf",&a[i][j]);
int t=gause();
if(t==0)
{
for(int i=0;i<n;i++) printf("%.2lf\n",a[i][n]);
}
else if(t==1) printf("Infinite group solutions");
else printf("No solution");
return 0;
}