1. 程式人生 > >【USACO3.2.4】飼料調配 純整數高斯消元

【USACO3.2.4】飼料調配 純整數高斯消元

其實就是高斯消元。 


但是常數項未知,但是常數項一定是題目給定的常數的整數倍(K倍),所以要窮舉一下這個K,然後做高斯消元。


但是如何判斷NONE呢?省事,多迴圈幾次,一直不出解,就是無解了。

最近得寫一個高斯消元的模板了……

/*
TASK:ratios
LANG:C++
*/
#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;

const int max_n = 5;


int equ, var;// 方程數量, var個變元  所以增廣矩陣有equ行,var +1 列 (最後一列為你懂的)
int a[max_n][max_n], ta[max_n][max_n];
int x[max_n]; //解集

int gcd(int a, int b){return a == 0 ? b : gcd(b % a , a);}
int lcm(int a, int b){return a / gcd(a, b) * b;}

bool guess()
{
	int row=0, col=0; //行,列
	for (; row != equ && col != var; ++ row, ++ col)
	{
		int max_row = row;
		for (int i = row + 1; i != equ; ++ i)	if (a[i][col] > a[max_row][col])	max_row = i;
		if (!a[max_row][col])	return false;
		for (int i = col; i <= var; ++ i)	swap(a[row][i], a[max_row][i]);
		for (int i = row + 1; i != equ; ++ i)
		{
			if (!a[i][col])	continue;
			int tmp = lcm(abs(a[row][col]), abs(a[i][col]));	
			int ta = tmp / a[row][col]; //正負,為他們自己的符號
			int tb = tmp / a[i][col];
			for (int j = col; j <= var; ++ j)	a[i][j] = a[i][j] * tb - a[row][j] * ta;
		}
	}
	row = equ - 1, col = var - 1;
	for (;row >= 0; -- row, -- col)
	{
		int tmp = a[row][var];
		for (int i = col + 1; i != var; ++ i)	tmp -= a[row][i] * x[i];
		if (tmp % a[row][col])	return false;
		x[col] = tmp / a[row][col];
		if (x[col] < 0)	return false;
	}
	return true;
}

void init()
{
	for (int i = 0; i != 3; ++ i)	cin >> ta[i][var];
	for (int i = 0; i != 3; ++ i)
		for (int j = 0; j != 3; ++ j)	 cin >> ta[j][i];
}

void doit()
{
	for (int ans = 1; ans <= 100; ++ ans)
	{
		for (int i = 0; i != 3; ++ i)	
			for (int j = 0; j != 4; ++ j)	a[i][j] = ta[i][j];
		for (int i = 0; i != 3; ++ i)	a[i][3] *= ans;
		if (guess())
		{
			for (int i = 0; i != var; ++ i)	cout<<x[i]<<" ";	
			cout<<ans<<endl;
			return;
		}
	}
	cout<<"NONE"<<endl;
}

int main()
{
//	freopen("ratios.in","r",stdin);
//	freopen("ratios.out","w",stdout);
	equ = var = 3;
	init();
	doit();
	return 0;
}