Gauss template

原创 2016年05月30日 14:02:14

learn from kuangbin

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
const int maxn = 50;
int a[maxn][maxn]; // zeng guang
int x[maxn] ; // ans_x
int free_x[maxn] ;
// 8 6 (6,2) (2,0)
inline int gcd(int a , int b) {
    return b == 0 ? a : gcd(b,a%b) ;
    /*int t ;
    while(b){
        t = b ;
        b = a%b ;
        a = t ;
    }
    return a;*/
}
inline int lcm(int a ,int b){
    return a/gcd(a,b)*b;
}
inline int abs(int a ){
    return a > 0 ? a : -a;
}
void debug(int equ , int var){
    for(int i = 0 ; i < equ ; ++i){
        for(int j = 0 ;j <= var ; ++j){
            cout << a[i][j] << " " ;
        }
        cout << endl;
    }
}
int Gauss(int equ , int var) {
    int max_r ;
    for(int i = 0 ; i <= var ; ++i){
        free_x[i] = false ;
        x[i] = 0 ;
    }
    //cout << equ << " " << var << endl;
    int row , col ;
    for(row = 0 ,col = 0 ; row < equ && col < var ; ++row , ++col) {
        max_r = row ;
        for(int i = row+1 ; i < equ ; ++i){         // find the max element in this col
            if(abs(a[max_r][col]) < abs(a[i][col])) max_r = i;
        }
        if(max_r != row){
            for(int j = col ; j <= var ; ++j){  // change
                swap(a[max_r][j],a[row][j]) ;
            }
        }
        if(!a[row][col]) {                  // 0
            row--;
            continue ;
        }
        //debug(3,3) ;
        for(int i = row+1 ; i < equ ; ++i){
            if(a[i][col]){// sub a[i][col] -> 0

                    int tmp = lcm(abs(a[i][col]),abs(a[row][col])) ;
                    int up = tmp/(abs(a[row][col])) ;
                    int down = tmp/(abs(a[i][col])) ;
                    //cout << tmp << " " << up << " " << down << endl;
                    if(a[i][col]*a[row][col]<0) up = -up ;
                for(int j = col ; j <= var; ++j){
                    a[i][j] = a[i][j]*down - a[row][j]*up ;
                }
            }
        }
    //system("pause") ;
    }
    // col == var  , [row,equ) == 皆是0000...an
    for(int i = row ; i < equ ; ++i){
        if(a[i][col] != 0) {
            return -1 ;         // no solve
        }
    }
    if(row < var){ //[row , equ -1 ] -> (000.000)  have free_x ,at least var - row . cal the x[]
            int free_index ;
        for(int i = row-1; i >= 0; --i){
            int free_num = 0 ;
            for(int j = i; j < var; ++j){
                if(a[i][j]&&(!free_x[j])) {
                    free_num++ ;
                    free_index = j ;
                }
            }
            if(free_num > 1) continue ; // free_x > 1 , can't solve
            // solve the free__index;
            int tmp = a[i][var] ;
            for(int j = i ; j < var ; ++j){
                if(a[i][j] && j != free_index) {
                    tmp -= a[i][j]*x[j] ;
                }
            }
            x[free_index] = tmp/a[i][free_index] ;      // solve the x of a[i][free_index] ;
            free_x[free_index] = true ;                 // solvable
        }
        return var - row ;
    }
    // only have one ans and must be the ans
    for(int i = equ-1 ; i >= 0 ; --i){
            int tmp = a[i][var] ;
        for(int j = i+1 ; j < var ; ++j){
                if(a[i][j])
            tmp -= a[i][j]*x[j] ;
        }
        // if(tmp%a[i][i] != 0 ) have the ans of double type
        x[i] = tmp/a[i][i] ;
    }
    return 0;
}
int main(){
    int t ;
    cin >> t ;
    while(t--){
            int equ , var ;
        cin >> equ >> var ;
        for(int i = 0 ;i < equ ; ++i){
            for(int j = 0; j <= var ; ++j){
                cin >> a[i][j] ;
            }
        }
        int tmp = Gauss(equ,var);
        if(tmp == -1 ) cout << "can't solve the question" << endl;
        else if(tmp == 0) cout << "there is only ans " << endl;
        else cout << "there have lots of ans" << endl;
        if(!tmp) {
            for(int i = 0 ;i < var ; ++i){
                cout << "x" << i << "is " << x[i] << endl ;
            }
        }
    }
/*
5
3 3
2 1 -1 8
0 1 1 2
0 2 1 5
x = 2 , y = 3  , z = -1
*/
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Gauss消元求线性方程解

  • 2014年04月04日 16:18
  • 1KB
  • 下载

高斯牛顿(Gauss Newton)、列文伯格-马夸尔特(Levenberg-Marquardt)最优化算法与VSLAM

高斯牛顿(Gauss Newton)、列文伯格-马夸尔特(Levenberg-Marquardt)最优化算法与VSLAM中的具体应用...

Gauss消元法

  • 2013年03月23日 16:32
  • 1KB
  • 下载

Gauss解线性方程组

  • 2010年11月16日 21:58
  • 480B
  • 下载

【python学习笔记】6:用Gauss-Legendre求积公式近似求积分值

高斯-勒让德求积公式给出了一个定积分的近似求法: 不妙的是这种求法对上下限要求为1和-1,但是因为积分可以变限,所以求任意定积分只要做变换就好: 用高斯公式求积分的近似值,精确度是非常高的,一...

hyperchem转gauss

  • 2007年11月18日 01:43
  • 80KB
  • 下载

Gauss-Bonnet定理

  • 2008年01月12日 21:26
  • 175KB
  • 下载

Jacobi迭代法与Gauss-Seidel迭代法

今天刚好有朋友和我讨论泊松图像融合算法,我说我过去文章里给出的是最原始、最直观的实现算法。对于理解泊松融合的原理比较有帮助,但是效率可能并不理想。印象中,泊松融合是有一个以矩阵为基础的快速算法的。但是...

数值计算 gauss

  • 2011年05月04日 12:53
  • 2KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Gauss template
举报原因:
原因补充:

(最多只允许输入30个字)