高斯消元模板

高斯消元:

其实就是用矩阵初等变换解线性方程组,只是他要求每次选取的主元一定要是最大值。

模板

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
const int MAXN=10000;
int a[MAXN][MAXN];//增广矩阵
int x[MAXN];//解集
bool free_x[MAXN];//标记是否是不确定的变元
int gcd(int a,int b)
{//最大公约数
    int t;
    while(b!=0)
    {
        t=b;
        b=a%b;
        a=t;
    }
    return a;
}
int lcm(int a,int b)
{//求最小公倍数
    return a/gcd(a,b)*b;//先除后乘防溢出
}
int Gauss(int equ,int var)
{
    int i,j,k;
    int max_r;// 当前这列绝对值最大的行.
    int col;//当前处理的列
    int ta,tb;
    int LCM,temp,free_x_num,free_index;
    for(int i=0; i<=var; i++)
    {
        //初始化
        x[i]=0;
        free_x[i]=true;
    }
//转换为行阶梯阵.
    col=0; // 当前处理的列  k为当前处理的行
    for(k = 0; k < equ && col < var; k++,col++)
    {
        //最后一列没有化解
//找到该col列元素绝对值最大的那行与第k行交换(为了在除法时减小误差)
        max_r=k;
        for(i=k+1; i<equ; i++)
        {
            if(abs(a[i][col])>abs(a[max_r][col]))
                max_r=i;
        }
        if(max_r!=k)
        {
            //与第k行交换.
            for(j=k; j<var+1; j++)
                swap(a[k][j],a[max_r][j]);
        }
        if(a[k][col]==0)
        {
//说明该col列第k行以下全是0了,则处理当前行的下一列.
            k--;
            continue;
        }
        for(i=k+1; i<equ; i++)
        {
            // 利用主元消元
            if(a[i][col]!=0)
            {
                LCM = lcm(abs(a[i][col]),abs(a[k][col]));
                ta = LCM/abs(a[i][col]);
                tb = LCM/abs(a[k][col]);
                if(a[i][col]*a[k][col]<0)
                    tb=-tb;//异号的情况是相加
                for(j=col; j<var+1; j++)
                    a[i][j] = a[i][j]*ta-a[k][j]*tb;
            }
        }
    }
// 1. 无解的情况有:0=d;
    for (i = k; i < equ; i++)
        if (a[i][col] != 0) return -1;
// 2. 无穷解的情况
    if (k < var)
    {
        //var是未知元个数,首先,自由变元有var - k个
        for (i = k - 1; i >= 0; i--)
        {
            free_x_num = 0;
            for (j = 0; j < var; j++)
                if (a[i][j] != 0 && free_x[j])
                    free_x_num++;
            free_index = j;
            if (free_x_num > 1) continue;
// 无法求解出确定的变元.
// 说明就只有一个不确定的变元free_index,那么可以求解出该变元,且该变元是确定的.
            temp = a[i][var];
            for (j = 0; j < var; j++)
            {
                //找已经求出的未知元
                if (a[i][j] != 0 && j != free_index)
                    temp -= a[i][j] * x[j];//移项
            }// 求出该变元.
            x[free_index] = temp / a[i][free_index];
            free_x[free_index] = 0; // 该变元是确定的.
        }
        return var - k; // 自由变元有var - k个.
    }
// 唯一解的情况:在var*(var + 1)的增广阵中形成严格的上三角阵.
// 计算出Xn-1, Xn-2 ... X0.
    for (i=var-1; i>=0; i--)
    {
        temp=a[i][var];
        for (j = i + 1; j < var; j++)
        {
            if (a[i][j] != 0) temp -= a[i][j] * x[j];
        }
        if (temp % a[i][i] != 0)
            return -2; // 说明有浮点数解,但无整数解.
        x[i] = temp / a[i][i];
    }
    return 0;
}
int main()
{
    int i, j;
    int equ,var;//行,列
    while (scanf("%d %d", &equ, &var) != EOF)
    {
        memset(a, 0, sizeof(a));
        for (i = 0; i < equ; i++)
        {
            for (j = 0; j < var + 1; j++)
            {
                //增广矩阵
                scanf("%d", &a[i][j]);
            }
        }
        int free_num = Gauss(equ,var);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-05 02:45:51

高斯消元模板的相关文章

高斯消元 模板

照着czyuan的那个模板,手敲了一遍,存一下. 貌似今天一整天就看了一下高斯消元的知识,然后看了模板,又手敲了一遍. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <algorithm> 7 #define LL __int64 8 const int

高斯消元模板(kuangbin大神版本)

#include<stdio.h> #include<algorithm> #include<iostream> #include<string.h> #include<math.h> using namespace std; const int MOD = 7; const int MAXN = 50; int a[MAXN][MAXN];//增广矩阵 int x[MAXN];//解集 bool free_x[MAXN];//标记是否是不确定的

HDU 3359 高斯消元模板题,

http://acm.hdu.edu.cn/showproblem.php?pid=3359 题目的意思是,由矩阵A生成矩阵B的方法是: 以a[i][j]为中心的,哈曼顿距离不大于dis的数字的总和 / 个数,就是矩阵B的b[i][j] 现在给出B,要求A 那么我们设A矩阵为a[1][1], a[1][2], a[1][3]..... 那么对于每一个b[i][j]我们有b[i][j] = (a[1][1] + a[1][2] + ... + ) / cnt 所以这样可以建议一条方程,然后guas

【Luogu】P3389高斯消元模板(矩阵高斯消元)

题目链接 高斯消元其实是个大模拟qwq 所以就着代码食用 首先我们读入 for(int i=1;i<=n;++i) for(int j=1;j<=n+1;++j) scanf("%lf",&s[i][j]); 读入肯定没什么问题(不过我在这卡了一分多钟) 然后我们要进行消元操作 所谓消元操作其实就是对于输入的矩阵 比如说 9 3 2 2 1 4 7 3 1 3 4 5 进行一番乱搞,使得第当前枚举的(比如说枚举第i行第i列)s[i][j]系数变成1. 实际上就是整行

【转】高斯消元模板 by kuangbin

写的很好,注释很详细,很全面. 原blog地址:http://www.cnblogs.com/kuangbin/archive/2012/09/01/2667044.html #include<stdio.h> #include<algorithm> #include<iostream> #include<string.h> #include<math.h> using namespace std; const int MAXN=50; int

高斯消元模板,整数(数学)

线性代数,原理不讲了... 1 /* 用于求整数解得方程组. */ 2 3 #include <iostream> 4 #include <string> 5 #include <cmath> 6 using namespace std; 7 8 const int maxn = 105; 9 10 int equ, var; // 有equ个方程,var个变元.增广阵行数为equ, 分别为0到equ - 1,列数为var + 1,分别为0到var. 11 int a[

高斯消元模板(pascal)

洛谷P3389评测 1 program rrr(input,output); 2 const 3 eps=1e-8; 4 var 5 a:array[0..110,0..110]of double; 6 n,i,j,k:longint; 7 t:double; 8 begin 9 assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output); 10 readln(n); 11 for i:=1 to n do f

【洛谷P3389】【模板】高斯消元

题目链接 题目描述 给定一个线性方程组,对其求解 输入输出格式 输入格式: 第一行,一个正整数 n 第二至 n+1行,每行 n+1 个整数,为a1, a2 .....an? 和 b,代表一组方程. 输出格式: 共n行,每行一个数,第 i行为 xi? (保留2位小数) 如果不存在唯一解,在第一行输出"No Solution". 输入输出样例 输入样例#1: 3 1 3 4 5 1 4 7 3 9 3 2 2 输出样例#1: -0.97 5.18 -2.39 说明 1≤n≤100,∣ai?

BZOJ 1013 JSOI2008 球形空间产生器sphere 高斯消元

题目大意:给定n维空间下的n+1个点,求这n个点所在的球面的球心 曾经尝试了很久的模拟退火0.0 至今仍未AC 0.0 今天挖粪涂墙怒学了高斯消元-- 我们设球心为X(x1,x2,...,xn) 假设有两点A(a1,a2,...,an)和B(b1,b2,...,bn) 那么我们可以得到两个方程 (x1-a1)^2+(x2-a2)^2+...+(xn-an)^2=r^2 (x1-b1)^2+(x2-b2)^2+...+(xn-bn)^2=r^2 这些方程都是二次的,无法套用高斯消元 但是我们可以做