Cod sursa(job #1823844)

Utilizator theodor.moroianuTheodor Moroianu theodor.moroianu Data 6 decembrie 2016 21:50:24
Problema Algoritmul lui Gauss Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.77 kb
#include <fstream>
#include <iostream>
#include <iomanip>
#define eps(x) ((x) > -1e-6 && (x) < 1e-6 ? true : false)
using namespace std;

double v[400][400];
double val[400];
int n, m; // n-> nr de linii, m -> nr de col - 1

void calc(int l, int c); /// calc de la linia l si coloana c
void sch(int l1, int l2); /// schimba doua coloane
void elim(int l1, int l2, int c); /// scade din l2 l1 * k a.i. v[l2][c] = 0
bool verif(); /// verifica daca este o solutie buna

int main()
{
	ifstream in("gauss.in");

	in >> n >> m;

	for (int i(1); i <= n; i++)
		for (int j(1); j <= m + 1; j++)
			in >> v[i][j];

	calc(1, 1);

	ofstream out("gauss.out");

	if (!verif()) {
		out << "Imposibil";
		return 0;
	}

	out << setprecision(9) << fixed;
	for (int i(1); i <= m; i++)
		out << val[i] << ' ';

	return 0;
}

bool verif()
{
	for (int i(0); i <= n; i++) {
		double r(0);
		for (int j(0); j <= m; j++)
			r += v[i][j] * val[j];
		if (r != v[i][m + 1])
			return false;
	}
	return true;
}

void calc(int l, int c)
{
	if (c == m) {
		if (!eps(v[l][c]))
			val[c] = v[l][c + 1] / v[l][c];
		return;
	}
	if (l > n || c > m)
		return;
	if (eps(v[l][c])) {
		for (int i(l + 1); i <= n; i++) {
			if (!eps(v[i][c])) {
				sch(i, l);
				break;
			}
		}
	}
	if (eps(v[l][c])) {
		calc(l, c + 1);
		return;
	}
	
	for (int i(l + 1); i <= n; i++)
		elim(l, i, c);

	calc(l + 1, c + 1);

	double s(0);
	for (int i(c + 1); i <= m; i++)
		s += v[l][i] * val[i];

	val[c] = (v[l][m + 1] - s) / v[l][c];
}

void sch(int l1, int l2)
{
	for (int i(0); i <= m + 1; i++)
		swap(v[l1][i], v[l2][i]);
}

void elim(int l1, int l2, int c)
{
	double imp = v[l2][c] / v[l1][c];
	for (int i(0); i <= m + 1; i++)
		v[l2][i] -= imp * v[l1][i];
}