zoukankan      html  css  js  c++  java
  • BZOJ 1013: [JSOI2008]球形空间产生器sphere 高斯消元

    原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1013

    题解:

    由所有点到圆心的距离都是相等的,我们可以列出n个方程式,其中第$i$个是这样的:

    $$sum_{j=1}^{n} 2*(a_{vj}-a_{uj})*P_j=sum_{j=1}^{n}-a_{uj}^2+a_{vj}^2$$

    其中$v=i+1,u=i$

    我们得到的解是$P$矩阵

    代码:

    /**************************************************************
        Problem: 1013
        User: HarryGuo2012
        Language: C++
        Result: Accepted
        Time:0 ms
        Memory:1276 kb
    ****************************************************************/
     
    #include<iostream>
    #include<vector>
    #include<cmath>
    #include<cstring>
    #include<iomanip>
    #define MAX_N 15
    using namespace std;
     
    const double EPS=1e-8;
     
    double a[MAX_N][MAX_N];
     
    int n;
     
    const int maxn=MAX_N;
    const double eps=1e-12;
    int equ,var;//equ个方程,var个变量
    double x[maxn];//解集
    bool free_x[maxn];
     
    int sgn(double x)
    {
        return (x>eps)-(x<-eps);
    }
    // 高斯消元法解方程组(Gauss-Jordan elimination).(0表示无解,1表示唯一解,大于1表示无穷解,并返回自由变元的个数)
    int gauss() {
        equ = n, var = n;//多少个方程,多少个变量
        int i, j, k;
        int max_r; // 当前这列绝对值最大的行.
        int col; // 当前处理的列.
        double temp;
        int free_x_num;
        int free_index;
        // 转换为阶梯阵.
        col = 0; // 当前处理的列.
        memset(free_x, true, sizeof(free_x));
        for (k = 0; k < equ && col < var; k++, col++) {
            max_r = k;
            for (i = k + 1; i < equ; i++) {
                if (sgn(fabs(a[i][col]) - fabs(a[max_r][col])) > 0)
                    max_r = i;
            }
            if (max_r != k) { // 与第k行交换.
                for (j = k; j < var + 1; j++)
                    swap(a[k][j], a[max_r][j]);
            }
            if (sgn(a[k][col]) == 0) { // 说明该col列第k行以下全是0了,则处理当前行的下一列.
                k--;
                continue;
            }
            for (i = k + 1; i < equ; i++) { // 枚举要删去的行.
                if (sgn(a[i][col]) != 0) {
                    temp = a[i][col] / a[k][col];
                    for (j = col; j < var + 1; j++) {
                        a[i][j] = a[i][j] - a[k][j] * temp;
                    }
                }
            }
        }
     
        for (i = k; i < equ; i++) {
            if (sgn(a[i][col]) != 0)
                return 0;
        }
        if (k < var) {
            for (i = k - 1; i >= 0; i--) {
                free_x_num = 0;
                for (j = 0; j < var; j++) {
                    if (sgn(a[i][j]) != 0 && free_x[j])
                        free_x_num++, free_index = j;
                }
                if (free_x_num > 1) continue;
                temp = a[i][var];
                for (j = 0; j < var; j++) {
                    if (sgn(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;
        }
     
        for (i = var - 1; i >= 0; i--) {
            temp = a[i][var];
            for (j = i + 1; j < var; j++) {
                if (sgn(a[i][j]) != 0)
                    temp -= a[i][j] * x[j];
            }
            x[i] = temp / a[i][i];
        }
        return 1;
    }
     
    double point[MAX_N][MAX_N];
     
    int main() {
        cin >> n;
        for (int i = 0; i < n + 1; i++)
            for (int j = 0; j < n; j++)
                cin >> point[i][j];
        for (int i = 0; i < n; i++) {
            double tmp = 0;
            for (int j = 0; j < n; j++) {
                a[i][j] = 2 * (point[i + 1][j] - point[i][j]);
                tmp += point[i + 1][j] * point[i + 1][j] - point[i][j] * point[i][j];
            }
            a[i][n] = tmp;
        }
        gauss();
        for (int i = 0; i < n; i++) {
            cout << setprecision(3) << fixed << x[i];
            if (i != n - 1)cout << " ";
        }
        cout << endl;
        return 0;
    }
  • 相关阅读:
    js正则表达式基本语法
    类似于QQ的右滑删除效果的实现方法
    JS设置cookie、读取cookie、删除cookie
    JavaScript随机生成颜色的方法
    mysql数据库备份及恢复
    Javascript 实现简单计算器实例代码
    JavaScript 实现的checkbox经典实例分享
    网页瀑布流布局jQuery实现代码
    Django Web在Apache上的部署
    VIM使用系列之一——配置VIM下C/C++编程环境
  • 原文地址:https://www.cnblogs.com/HarryGuo2012/p/4852470.html
Copyright © 2011-2022 走看看