• U66785 行列式求值


    二更:把更多的行列式有关内容加了进来(%%%%%Jelly Goat奆佬)

    题目描述

    给你一个N(n≤10nleq 10n10)阶行列式,请计算出它的值

    输入输出格式

    输入格式:

    第一行有一个整数n
    在以下n行中,每行有n个整数,表示该行列式

    输出格式:

    这个行列式的值

    输入输出样例

    输入样例#1: 
    8
    2 10 4 4 3 6 10 6
    1 10 9 3 2 1 6 7
    3 9 8 7 1 1 8 7
    2 10 8 6 9 9 3 4
    1 7 1 8 2 6 2 3
    9 2 4 8 10 6 10 3
    3 6 7 9 8 2 8 1
    2 9 2 1 10 7 4 5
    输出样例#1:
    -135742
    输入样例#2: 
    4
    1 2 3 4
    1 3 4 1
    1 4 1 2
    1 1 2 3
    输出样例#2: 
    16
    首先这是一道非常简单的板子题,他耗费了我两天将近两个多小时的时间,那么我们就来细细分析一下这道题
    思路大致如下:

    按照高斯消元法,把行列式消成下三角,然后按照公式直接求对角线乘积即为答案
    有这么几个坑
    1.忘记用double类型,因为行列式做除法的时候肯定是要出小数的,不用double肯定gg
    2.没有注意当a[i][i]==0的时候,我们没法按照公式把它下面消为零,所以需要一个换行操作
    代码如下
    while (a[i][i] == 0 && sum<=n) //对是否a[i][i]是0的特判
            {
                CH2(i, sum + 1); //交换x列和y列
                ans *= -1;
                sum++;
            }
    3.输出的时候忘记控制精度,其实原因是这样的,在小数点后位数多于18个之后,c++会自动转成科学计数法。。。。。。
    但是洛谷不认啊喂!!!!!!!,所以输出的时候手动控制一下就好
      printf("%0.0lf", ans);
    4.各种奇奇怪怪的诸如循环控制写错了或者是while条件判错了的诡异失误,导致我挂了整整五次
    不过这种经历也的确是能让我深刻的记住这道题了吧。
    现在贴一下AC代码
    #include <iostream>
    #include <string>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    double n, a[20][20], ans = 1;
    int sum;
    inline void CH1(int x, int y, double k) //第y行减k*x
    {
        for (int i = 1; i <= n; ++i)
            a[y][i] -= (double)(k * a[x][i]);
    }
    inline void CH2(int x, int y) //交换x列和y列
    {
        for (int i = 1; i <= n; ++i)
            swap(a[i][x], a[i][y]);
    }
    inline double CH3(int x, double k) //把第x行提出一个公因数k
    {
        for (int i = 1; i <= n; ++i)
            a[x][i] /= k;
        return k;
    }
    int main()
    {
        scanf("%lf", &n);
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j)
                scanf("%lf", &a[i][j]);
        for (int i = 1; i < n; ++i)
        {   
            sum=i;
            while (a[i][i] == 0 && sum<=n) //对是否a[i][i]是0的特判
            {
                CH2(i, sum + 1); //交换x列和y列
                ans *= -1;
                sum++;
            }
            ans *= CH3(i, a[i][i]);
            for (int j = i + 1; j <= n; ++j)
                CH1(i, j, a[j][i]);
        }
        for (int i = 1; i <= n; ++i)
            ans *= a[i][i];
        printf("%0.0lf", ans);
        return 0;
    }
    
    
    
     
  • 相关阅读:
    【博弈论】囚徒困境
    【LTE与5G】
    【现代通信技术】绪论
    【操作系统】 逻辑结构
    【密码学】
    【计算机网络】网络应用
    部署docker仓库-Harbor
    ELK+filebeat收集K8S平台日志
    istio-http流量管理
    K8S集群部署istio
  • 原文地址:https://www.cnblogs.com/this-is-M/p/10698562.html
Copyright © 2020-2023  润新知