1. 程式人生 > 遊戲 >英國周榜:《地平線:西之絕境》同捆版助其重回巔峰

英國周榜:《地平線:西之絕境》同捆版助其重回巔峰

高斯消元

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iomanip>
using namespace std;
typedef long long ll;
const int N = 1e2 + 10;

const double eps = 1e-6;
int n;
double a[N][N];
void print()
{
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n + 1; j++)
			cout << left << setw(8) << a[i][j] << " ";
		cout << endl;
	}
	cout << endl;
}
int guess()
{
	int r, c;
	for (c = 1, r = 1; c <= n; c++)
	{
		int t = r;//本輪處理r ~ n行,1 ~ r-1 行已處理,不能再變化
		for (int i = r; i <= n; i++)//找到當前列最大的數
		{
			if (fabs(a[i][c]) > fabs(a[t][c]))
				t = i;
		}
		if (fabs(a[t][c]) < eps)//如果當前列全是0,則跳過看下一列,此時只有c++, r不變,最終以r <= n來判斷解的情況
			continue;
		for (int i = c; i <= n + 1; i++)//將該列最大的數所在行換到第 r 行
			swap(a[r][i], a[t][i]);
		for (int i = n + 1; i >= c; i--)//將第 r 行的第一個非零元素變為 1
			a[r][i] /= a[r][c];
		for (int i = r + 1; i <= n; i++)//將 r+1 ~ n 行的第 c 列全部變為 0
		{
			if (fabs(a[i][c]) > eps)
				for (int j = n + 1; j >= c; j--)
					a[i][j] -= a[r][j] * a[i][c];
		}
		r++;
	}
	//print();
	if (r <= n)//若係數矩陣每行都不是全 0,r應為n+1
	{
		//若r <= n, 則係數矩陣的 r ~ n 行全為 0,此時若最後一列有非 0 數,則無解
		for (int i = r; i <= n; i++)
			if (fabs(a[i][n+1]) > eps)
				return 2;
		return 1;
	}
	for (int i = n; i >= 1; i--)//若有唯一解則迴帶,將階梯矩陣變為對角型矩陣
	{
		for (int j = i + 1; j <= n; j++)
			a[i][n+1] -= a[j][n+1] * a[i][j];
	}
	return 0;
}
int main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n + 1; j++)
			cin >> a[i][j];
		int t = guess();
		
	if (t == 0)
        for (int i = 1; i <= n; i++)
        {
            if (fabs(a[i][n+1]) < eps)//防止輸出"-0"
                a[i][n+1] = 0;
            printf("%.2lf\n", a[i][n+1]);
        }
        	
    else if (t == 1)
    	puts("Infinite group solutions");
    else
    	puts("No solution");

	return 0;
}