首页 > 其他分享 >矩阵

矩阵

时间:2024-07-28 20:06:53浏览次数:5  
标签:int ll 矩阵 行列式 include mod

矩阵

高斯消元

没啥好说的,直接上代码:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
double a[105][105];
int main()
{
    int n;
    cin >> n;
    for(int i = 1;i <= n;i++)
        for(int j = 1;j <= n+1;j++)
            cin >> a[i][j];
    for(int i = 1;i <= n;i++)
    {
        int ma = i;
        for(int j = i+1;j <= n;j++)
            if(fabs(a[j][i]) > fabs(a[ma][i]))ma = j;
        for(int j = 1;j <= n+1;j++)swap(a[i][j],a[ma][j]);
        if(!a[i][i]){cout << "No Solution";return 0;}
        for(int j = 1;j <= n;j++)
            if(i != j)
                for(int k = i+1;k <= n+1;++k)
                    a[j][k] -= a[i][k]*(a[j][i]/a[i][i]);
    }
    for(int i = 1;i <= n;i++)
        printf("%.2lf\n",a[i][n+1]/a[i][i]);
    return 0;
}

行列式求值

定义:

\(det(A)=\mid A\mid =\sum\limits_p(-1)^{\tau(p)}\mathop{\Pi}\limits_{i=1}^na_{i,p_i}\)

其中 \(p\) 表示一个排列,\(\tau(p)\) 表示排列中逆序对的个数,即排列的奇偶性。

行列式的一些性质(感性理解即可):

  • 交换矩阵的两行,行列式取反;
  • 交换矩阵 \(1\) 行于 \(1\) 列,行列式不变;
  • 如果矩阵 \(A\) 中有一行(列),矩阵 \(B,C\) 中分别对应的 \(2\) 行(列)的元素之和,那么 \(\det(A)=\det(B)+\det(C)\);
  • 如果矩阵 \(A\) 两行成比例,则 \(det(A)=0\);
  • 把一个矩阵一行(列)的值全部乘一个常数加到另一行(列)上,行列式值不变。

行列式求值

根据以上性质,可以类似高斯消元将矩阵消成上三角矩阵,但是这里有模数,必须辗转消除来消元。

代码:

#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
const int N = 605;
int n,mod;
ll a[N][N];
ll solve()
{
    bool w = 1;
    for(int i = 1;i <= n;i++)
        for(int j = 1;j <= n;j++)
        {
            if(i==j)continue;
            while(a[i][i])
            {
                int now = a[j][i]/a[i][i];
                for(int k = i;k <= n;k++)
                    a[j][k] = (a[j][k]-now*a[i][k]%mod+mod)%mod;
                swap(a[i],a[j]);w = !w;
            }
            swap(a[i],a[j]);w = !w;
        }
    ll ans = 1;
    for(int i = 1;i <= n;i++)(ans *= a[i][i]) %= mod;
    return (w?ans:-ans);
}
inline int rd()
{
    char c;int f = 1;
    while((c = getchar())<'0'\mid \mid c>'9')if(c=='-')f = -1;
    int x = c-'0';
    while(('0' <= (c = getchar()))&&c <= '9')x = x*10+(c^48);
    return x*f;
}
int main()
{
    n = rd();mod = rd();
    for(int i = 1;i <= n;i++)
        for(int j = 1;j <= n;j++)
            a[i][j] = rd();
    cout << (solve()+mod)%mod;
    return 0;
}

参考链接:行列式 - Rey の 棚屋 - 洛谷博客

矩阵求逆

定义:

设 \(A\) 是一个方阵,如果存在一个矩阵 \(A^{-1}\) 使得 \(AA^{-1}=I\) 且 \(A^{-1}A=I\),那么矩阵 \(A\) 就是可逆的,\(A^{-1}\) 就是 \(A\) 的逆矩阵。

高斯-约旦消元

高斯-约旦消元与高斯消元的区别在于:高斯-约旦消元是消成对角矩阵,而普通高斯消元是消成上三角矩阵。

高斯-约旦消元:

void Gauss_jordan(){
    /***** 行的交换&加减消元 *****/ 
    for(re int i=1,r;i<=n;++i){ //正在处理第i行 
        r=i;
        for(re int j=i+1;j<=n;++j) 
            if(fabs(a[j][i])>fabs(a[r][i])) r=j;
        if(fabs(a[r][i])<eps){
            puts("No Solution");return;
        }
        if(i!=r) swap(a[i],a[r]);
        for(re int k=1;k<=n;++k){
        //每一行都处理  
            if(k==i) continue;
            double p=a[k][i]/a[i][i];
            for(re int j=i;j<=n+1;++j) a[k][j]-=p*a[i][j];
        } 
    }   
    //上述操作后会剩下对角矩阵,答案要除以系数    
    for(re int i=1;i<=n;++i) printf("%.2lf\n",a[i][n+1]/a[i][i]);
}

矩阵求逆

思路:

  • 将 \(A\) 和 \(I\) 放在一个矩阵中
  • 将 \(A\) 消元成单位矩阵
  • 此时原来的 \(I\) 变为 \(A\) 的逆矩阵
#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
const int N = 405,mod = 1e9+7;
int n;
ll a[N][N << 1];
ll qp(ll x,int y)
{
    ll ans = 1;
    for(;y;y >>= 1,x = x*x%mod)
        if(y&1)(ans *= x) %= mod;
    return ans;
}
void solve()
{
    for(int i = 1;i <= n;i++)
    {
        int r = i;
        for(int j = i+1;j <= n;j++)
            if(a[j][i] > a[r][i])r = j;
        if(r != i)swap(a[i],a[r]);
        if(!a[i][i]){puts("No Solution");return ;}
        ll now = qp(a[i][i],mod-2);
        for(int j = 1;j <= n;j++)
        {
            if(i==j)continue;
            ll p = now*a[j][i]%mod;
            for(int k = i;k <= n*2;k++)
                a[j][k] = (a[j][k]-p*a[i][k]%mod+mod)%mod;
        }
        for(int j = 1;j <= n*2;j++)(a[i][j] *= now) %= mod;
    }
    for(int i = 1;i <= n;i++)
        for(int j = n+1;j <= n*2;j++)
            printf("%lld%c",a[i][j],j==n*2?'\n':' ');
}
inline int rd()
{
    char c;int f = 1;
    while((c = getchar())<'0'\mid \mid c>'9')if(c=='-')f = -1;
    int x = c-'0';
    while(('0' <= (c = getchar()))&&c <= '9')x = x*10+(c^48);
    return x*f;
}
int main()
{
    n = rd();
    for(int i = 1;i <= n;i++)
        for(int j = 1;j <= n;j++)
            a[i][j] = rd(),a[i][n+i] = 1;
    solve();
    return 0;
}

标签:int,ll,矩阵,行列式,include,mod
From: https://www.cnblogs.com/max0810/p/18328778

相关文章

  • 可逆矩阵的概念、定理、判断条件和性质(线性代数基础)
    可逆矩阵的概念、定理、判断条件和性质可逆矩阵的概念定义:设AAA为n......
  • 题解 - 矩阵
    题目描述小明和小花知道学信息学竞赛的学生特别擅长做一些和矩阵相关的问题。例如,同学经常做的一个题目,给你一个N×M的矩阵,矩阵里面每个格子上都有一个数,要从左上角(1,1),走到右下角(N,M),每一步只能往下或者往右走,让你求经过的路径上数的总和最小。小明和小花发现这个......
  • 如何比较两个大的温度矩阵数据集并对差异/相似之处进行分类?我如何继续寻找好的方法?
    我有以下问题:我想在python中比较热图像(数据以一个大矩阵/每个像素一个值的形式出现)并了解它们的不同。哪些统计方法是相关的?我如何继续找到一个好的测试?在python中比较矩阵/图片的其他方法是什么?我有一些数据集,并且知道其中一些数据应该被测试视为不同的,而有些数据应该被......
  • 矩阵的奇异值分解(SVD)及其应用
    奇异值分解(SingularValueDecomposition,SVD)是矩阵的一种分解方法,与特征值分解不同,它可以应用于长方矩阵中,并将其分解成三个特殊矩阵的乘积。此外SVD分解还具有许多优良的性质,在图像压缩,数据降维和推荐系统等算法中都具有广泛的应用。奇异值分解的引入我们考虑二维的情形,考虑......
  • 矩阵乘法写法比较
    免责声明测的比较随意,有吹黑哨的嫌疑。看一下就好了。测试对象\(n=1000\),测试\(n\timesn\)矩阵乘\(n\timesn\)的atcoder::modint998244353的矩阵乘法速度。矩阵数字生成:mt19937rng{1}正确结果矩阵元素异或和:6597111编译选项: g++$<-o$@-O2-std=c++14-static......
  • 24矩阵杯线下赛
    24矩阵杯线下赛是在6月26日-6月27日最终排名在27名比赛内容是内网渗透,基本上都是用工具扫签了保密协议,题目不让放出来这个比赛是由360安全举办的,包路费,酒店费,就感觉挺好的比赛结束之后,晚上是聚会,有抽奖,我抽到了贴纸和U盘,运气爆棚。......
  • 2024矩阵杯初赛
      矩阵杯WP没问题的话就进决赛了 一眼看是USB流量  但这题不考,回到题目CTF异世界的代码监察员lulu猪的照片被人偷拷贝走时触发了保护机制,不仅对图片进行了隐写术.js的加工,还留下了传输的痕迹,神奇的Misc选手能证明这张图片是被偷拷走的吗再看看提示:Tointroduceyou,......
  • tensor对张量和矩阵的操作
    点击查看代码#-*-coding:utf-8-*-#@Author:钱力#@Time:2024/7/2610:36importtorcha=torch.arange(5)b=a[2:]#截取a的部分值print('a',a)print('b',b)#打印存储地址#可以发现他们共用存储区#b的索引比a偏移了2位print(a.untyped_storage......
  • 基于GD32的矩阵按键usb-hid设备,详细教程,完全模拟的电脑数字键盘的所有功能,包括长按、
    本文采用的是基于GD32F350的一个4×5的矩阵键盘键盘板。矩阵键盘的电路原理图大致如下,由四个列引脚和五个行引脚来检测判断按键的按下。本文四个列引脚分别是PA15PB8PB9PC13,五个行引脚分别是PB10PB11PB12PB13PB14。typedefstruct{uint32_tGPIO_Group;......
  • 如何使用 NumPy 根据值在矩阵中的出现情况来组织值?
    我正在做一个练习,需要根据3x3矩阵中的出现情况将0到5之间的值组织到一个数组中。我正在使用NumPy来完成此任务。给定以下3x3矩阵:[[113][452][300]]我想输出一个数组,其中每个元素代表从0到5的每个值出现的次数。对于上述矩阵,所需的输出是:[2,2......