Jimmy Blog

Welcome!

高斯消元法-hihocoder 1166

解一元几次方程的方法:

1、一般迭代法

2、牛顿迭代法

解多元一次方程的方法:

高斯消元法

可参考:http://www.docin.com/p-301431993.html

模板

输入:matrix[],最后一列为系数为0的列。

输出:ans[]

//高斯消元法
/**** **** **** **** **** ****
*     Function Name :          高斯消元法
*     Description :             求解线性方程组
*
*     void exchange_col(int p1,int p2,int n)  
*     交换p1行和p2行的所有数据
*
*     bool gauss(int n)
*     求解系数矩阵为n的线性方程组,方程组无解返回false,否则true
*
*   x1 = x0 - f(x0)/f'(x0)   牛顿迭代法
**** **** **** **** **** ****/ 

const int num = 100;
double matrix[num][num + 1];   //系数矩阵,从0开始 最后一列是0系数
double ans[num];               //结果数组

void exchange_col(int p1,int p2,int n)  //交换p1行和p2行的所有数据
{
     double t;
     int i;

     for(i = 0 ; i <= n ; i++)
          t = matrix[p1][i],matrix[p1][i] = matrix[p2][i],matrix[p2][i] = t;
}

bool gauss(int n)   //求解系数矩阵为n的线性方程组
{
     int i,j,k;
     int p;
     double r;

     for(i = 0 ; i < n - 1 ; i++) {
          p = i;
          for(j = i + 1 ; j < n ; j++) {   //寻找i列最大值位置
               if(matrix[j][i] > matrix[p][i])
                    p = j;
          }
          if(matrix[p][i] == 0) return false;
          if(p != i)     exchange_col(i,p,n);
          for(j = i + 1 ; j < n ; j++) {       //剩余列进行消元
               r = matrix[j][i] / matrix[i][i];
               for(k = i ; k <= n ; k++)
                    matrix[j][k] -= r * matrix[i][k];
          }
     }
     for(i = n - 1 ; i >= 0 ; i--) {   //获得结果
          ans[i] = matrix[i][n];
          for(j = n - 1 ; j > i ; j--)
               ans[i] -= matrix[i][j] * ans[j];
          ans[i] /= matrix[i][i];
     }
     return true;
}

例题

hihocoder 1166 http://hihocoder.com/problemset/problem/1166

解法:http://media.hihocoder.com/contests/challenge11/hihoCoderChallenge11SolutionsB-D.pdf

代码:

#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cstdio>

using namespace std;

const double eps = 0.00001;


int N;
double P;

const int num = 21;
double matrix[num][num + 1];   //系数矩阵,从0开始
double ans[num];               //结果数组

void exchange_col(int p1, int p2, int n)  //交换p1行和p2行的所有数据
{
    double t;
    int i;

    for (i = 0; i <= n; i++)
        t = matrix[p1][i], matrix[p1][i] = matrix[p2][i], matrix[p2][i] = t;
}

bool gauss(int n)   //求解系数矩阵为n的线性方程组
{

    int i, j, k;
    int p;
    double r;

    for (i = 0; i < n - 1; i++) {
        p = i;
        for (j = i + 1; j < n; j++) {   //寻找i列最大值位置
            if (matrix[j][i] > matrix[p][i])
                p = j;
        }
        if (matrix[p][i] == 0) return false;
        if (p != i)     exchange_col(i, p, n);
        for (j = i + 1; j < n; j++) {       //剩余列进行消元
            r = matrix[j][i] / matrix[i][i];
            for (k = i; k <= n; k++)
                matrix[j][k] -= r * matrix[i][k];
        }
    }
    for (i = n - 1; i >= 0; i--) {   //获得结果
        ans[i] = matrix[i][n];
        for (j = n - 1; j > i; j--)
            ans[i] -= matrix[i][j] * ans[j];
        ans[i] /= matrix[i][i];
    }
    return true;
}


void Init(int n)
{
    memset(matrix, 0, sizeof(matrix));
    matrix[0][0] = 1.0;
    for (int i = 1; i < n; i++)
    {
        double x = (double)i * 2, dn = (double)N;
        double a = x *(x - 1) / dn / (dn - 1),
            c = (dn - x)*(dn - x - 1)/dn/(dn - 1),
            b = 0 - a - c;
        matrix[i][i - 1] = a;
        matrix[i][i] = b;
        matrix[i][i + 1] = c;
        matrix[i][n] = -1;
    }

}

int main()
{
    cin >> N;
    int x = 0;
    int prev = 0;
    for (int i = 0; i < N; i++)
    {
        int a;
        cin >> a;

        x += a ^ prev;
        prev = a;
    }
    x += 0 ^ prev;

    N++;

    Init(N / 2 + 1);
    gauss(N / 2 + 1);

    printf("%.6lf\n", ans[x / 2]);

    return 0;
}

comments powered by Disqus