C++求行列式(满足一般性的解法)

2023-10-28

突发奇想对y总的模板进行如下应用,如有不当,还望斧正

由行列式的定义,不同行不同列的n个元素的乘积,当这个乘积列的下标的逆序对个数为偶数时,该项为正,当这个乘积列的下标的逆序对个数为奇数时,该项为负,那么我们需要写一个函数来求出这些数的逆序对个数。

int merge_sort(int l,int r)
{
    if(l >= r) return 0;// 先判断区间左右端点是否合理
    int mid = l + r >> 1;  
    int i = l ,j = mid + 1,k = 0; 
    int res = merge_sort(l,mid) + merge_sort(mid + 1,r);//先递归左右两个区间排好序并求出各自区间的逆序对数量
    while (i <= mid && j <= r)//指针不超过范围
    if(a[i] <= a[j] ) temp[k++] = a[i++]; //左区间小的存入临时数组
    else{
        temp[k++] = a[j++]; //右区间小的存入临时数组
        res += mid - i + 1; //此时存在逆序对,a[i]>a[j] ,即a[i~mid]>a[j] ,逆序对数量为mid-i+1
    }       //与此同时,有一个区间已经遍历完毕且这区间的逆序对数量已经全部求出,下面进行扫尾
    while(i <= mid) temp[k++] = a[i++]; //扫尾,若左区间有剩余,依次存入临时数组
    while(j <= r) temp[k++] = a[j++];   //扫尾,若右区间有剩余,依次存入临时数组
    for(int i = l,k = 0;i <= r;i++,k++)     // 将临时数组的内容赋给原数组
    a[i] = temp[k];
    return res;
} 

这是归并排序的应用,在排好序的同时求出其中的逆序对数量

接下来就是求不同行不同列的n个元素,这里就需要用到DFS深度优先遍历来求出所有可能的情况,

从第一行开始列出该行可以存在的列数,第二行列出除第一行外的所有列数,以此类推,可以

求出所有的排列(类似于不需要满足对角线与反对角线条件的N皇后问题)

void dfs(int u) 
{
    if(u == n) 
    {
       ........
    }
    for(int i = 1;i <= n; i ++) //对于第u层对1~n这些数依次遍历
    {   
        if(!st[i])   //如果第u层的数i没有被用过,那么
        {
            a[u] = i;//第u个数就是i
            st[i] = true;//更新此时的i是被用过的状态
            dfs(u + 1);  //那么对u+1层进行上述操作
            st[i] = false; //当u+1层及其下面的层都进行过上述操作之后,恢复数i的状态
        }
    }
}

通过上述分析可得,用DFS来求出所有的行列组合并进行求积,对所例举出来的列数求其逆序对的个数,如果模2为1则需要加上负号,在对这些积求和即可求出一般情况下的行类似的值

if(u == n)
    {
        int sy = 1;//每列一种情况乘积就必须初始化为1,否则sy依然为上一种情况的积对后续结果会产生影响
        for(int i = 0;i < n ; i++)
        {
            sy *= g[i][a[i] - 1];//存放不同行列的积
        }
        ++z;
       if(merge_sort(0,n-1) % 2 == 1) sy = -sy;//判断这种排列的逆序对数,从而进行符号的判断
           /*  该行存在错误,该判断会影响了全排列的结果,若删除该行则不会对全排列的结果产生影响,但就无法判断符号 */
            sum[z] = sy + sum[z-1];//sum[z]依次存储各式之并取最后一次的运算结果为最终结果
    }

如果是这样,那么运算结果就出现了偏差。笔者在初次编写时就遇到了该问题,在将所有的操作显示出来后发现,merge_sort该函数对所应该产生的排列情况产生了影响,从而对乘积的正负号产生影响。如图所示

在进行分析后可以发现由于merge_sort函数在求逆序对数量的同时将该数组排好了序以至于对后面的排列情况产生了影响(虽然merge_sort改变了原来数组的顺序,但是其时间复杂度为O(n * log n)比暴力做法快不少),如果需要解决这个问题,那么我们需要用一个数组b来暂存排列好的情况,再对其用merge_sort求逆序对数量,求完后需要将数组b再赋值给原来的排列情况。 

综上所述,源代码如下

#include <iostream>
using namespace std;
const int N = 10;
bool st[N];//用于存储1~n这些数是否被用过
int n;
int a[N],temp[N]; //创建一个临时数组来存放
int g[N][N];
int merge_sort(int l,int r)
{
    if(l >= r) return 0;
    int mid = l + r >> 1;
    int i = l ,j = mid + 1,k = 0;
    int res = merge_sort(l,mid) + merge_sort(mid + 1,r);//先递归左右两个区间排好序
    while (i <= mid && j <= r)
    if(a[i] <= a[j] ) temp[k++] = a[i++];
    else{
        temp[k++] = a[j++];
        res += mid - i + 1;
    }
    while(i <= mid) temp[k++] = a[i++];
    while(j <= r) temp[k++] = a[j++];
    for(int i = l,k = 0;i <= r;i++,k++)
    a[i] = temp[k];
    return res;
} 
int sum[N * N * N],z = 0; 
int b[N];//用来存储原先的排列顺序
void dfs(int u)
{
    if(u == n)
    {
        int sy = 1;
        for(int i = 0;i < n ; i++)
        {
           //printf("%d ",a[i]);
            sy *= g[i][a[i] - 1];//存放不同行列的积
            b[i] = a[i];
        }
        ++z;
        int res = merge_sort(0,n-1);
        //printf("%d ",res);
        for(int i = 0;i < n;i++)
        {
            a[i] = b[i];
        }
       if(res % 2 == 1) sy = -sy;//判断这种排列的逆序对数,从而进行符号的判断
        //  printf("%d\n",sy); 
           sum[z] = sy + sum[z-1];//sum[z]依次存储各式之和取最后一次的运算结果为最终结果
    }
    for (int i = 1;i <= n;i++)
    {
        if(!st[i])
        {
            a[u] = i;
            st[i] = true;
            dfs(u + 1);
            st[i] = false;
        }
    }
}
int main()
{
    scanf("%d",&n);
    for(int i = 0;i < n;i++)
    for(int j = 0;j < n;j++)
    scanf("%d",&g[i][j]);
    dfs(0);
    printf("%d",sum[z]);
}

输入测试

三阶:

 范德蒙德行列式:

          特别的如果行列式的阶数大于6,则需要将源代码中的sum数组的长度改大

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++求行列式(满足一般性的解法) 的相关文章

  • 数据结构——图的深度优先遍历(DFS)

    本文内图的存储方式是邻接矩阵 FS的遍历方法可以类比树的先序遍历 在实现树的先序遍历时 遍历顺序是 根 子树 下一个子树 而DFS的实现方法是优先深度 与一个树按照先序遍历的顺序相同 所以在实现DFS之前 需要先学习 寻找第一个邻接点 Fi
  • 8-13外部排序-败者树

    败者树是树形选择排序的一种变体 可视为一棵完全二叉树 通过败者树 可以在k个归并段中选出最小关键字所需要的关键字对比次数更少 绿色为叶子结点 存放初始数据 黑色为失败结点 蓝色为胜出结点 一 基本过程 以下按从小到大的方式构建 1 从8个归
  • Permutation 和 Combination

    文章目录 Permutation 代码 代码核心思路 Combination 代码 代码核心思路 总结 Permutation 和 Combination是算法中非常常见的两种数据的排列方式 也就是数学中的排列和组合 Permutation
  • Acwing 842. 排列数字

    dfs int u 搜索第u个位置上可以放哪个数字 include
  • LeetCode刷题-9

    数组 119 杨辉三角 II 题目描述 题目样例 Java方法 线性递推 思路及算法 代码 复杂度 题目描述 给定一个非负索引 rowIndex 返回 杨辉三角 的第 rowIndex 行 在 杨辉三角 中 每个数是它左上方和右上方的数的和
  • 【数据结构与算法】--排序

    目录 一 排序的概念及其运用 二 常见的排序算法 2 2选择排序 2 3 交换排序 2 3 4 1 快速排序优化 一 排序的概念及其运用 1 1 排序的概念 排序 所谓排序 就是使一串记录 按照其中的某个或某些关键字的大小 递增或递减的排列
  • 大数据量的冒泡排序 (计次数)

    题目描述 给定一个包含从0到n 1各一次的数组 若使用冒泡排序将其排为升序 问其中需要进行多少次交换 输入 测试数据有多组 每组由两行组成 第一行包含正整数n n lt 5000 下一行包含从0到n 1的n个整数的序列 输出 对于每组测试数
  • 【数据结构】排序(直接插入、折半插入、希尔、冒泡、快速、直接选择、堆、归并、基数排序)

    一 什么是排序 排序 将一组杂乱无章的数据按一定规律顺次排列起来 即 将无序序列的数据节点包含多个数据域 那么排序往往是针对其中某个域而言 二 排序方法的分类 1 按数据存储介质可分为 内部排序 数据量不大 数据在内存 无需内外存交换数据
  • 滑雪(记忆化搜索)

    题目 题解 记忆化搜索模板题 记忆化搜索的核心 本质是带剪枝的深搜 当某点的dp已赋值时 返回该值 其他情况进行深度搜索 模板 dfs u点 if u点的 dp 已经有值了 return u点的 dp 值 else 说明第一次到达u 则为u
  • 数据结构--排序之快速排序

    个人主页 你帅你先说 欢迎点赞 关注 收藏 既选择了远方 便只顾风雨兼程 欢迎大家有问题随时私信我 版权 本文由 你帅你先说 原创 CSDN首发 侵权必究 快速排序基本思想及其代码实现 快速排序是Hoare于1962年提出的一种二叉树结构的
  • C++容器排序算法的简单应用

    功能实现 1 去掉所有重复的单词 2 按照单词的长度进行排序 3 统计长度等于或者超过6个字符的单词个数 4 按照单词的长度顺序进行输出 include
  • 数据结构——哈希排序

    哈希排序 就是用空间换取时间的一种排序方式 空间利用率达O n 算法思想 如果一个元素序列a里没有重复的元素 而我们需要找最大值或者前几个最大值时 怎么办呢 1 将这个a序列排序 然后直接选出目标值 2 开辟一个b数组 a里的每一个元素对应
  • 如何学好C语言的数据结构与算法?

    C语言的数据结构与算法 难就难在链表 学会了链表 可能后面就一点都不难了 书籍推荐 数据结构与算法分析 C语言描述版 要深入学习的话可以选择这本书 因为针对链表的讲解是比较详细的 所以可以很快理解链表 跟着书上一点点实现基本操作 增删改查
  • 【数据结构】带你手撕八大排序

    目录 一 排序的基础知识 1 排序的概念 2 排序的应用 3 常见的排序算法 二 八大排序的实现 1 插入排序 直接插入排序 直接插入排序的特性总结 2 插入排序 希尔排序 希尔排序的特性总结 3 选择排序 直接选择排序 直接插入排序特性总
  • 2023华为OD机试真题【双指针/优雅子数组】

    题目内容 如果一个数组中出现次数最多的元素出现大于等于K次 被称为K 优雅数组 k也可以被称为优雅阈值 例如 数组1 2 3 1 2 3 1 它是一个3 优雅数组 因为元素1出现次数大于等于3次 数组1 2 3 1 2就不是一个3 优雅数组
  • 【快速选择算法】O(n)时间复杂度

    快速选择的期望时间复杂度为O n 最坏时间复杂度为O n 2 当每次划分只划分为n 1个和1个时 由于划分时间复杂度为O n 最坏时间复杂度为O n 2 void quickselect vector
  • 分治-归并算法——LCR 170. 交易逆序对的总数

    文章目录 0 归并排序 1 题目 2 算法原理 3 代码实现 0 归并排序 归并排序是典型的分治 将数组分成若干个子数组 数组两两比较 不是很清楚的 可以查看此篇文章 数据结构 七大排序 这里以力扣 9
  • 分治-归并排序

    文章目录 315 计算右侧小于当前元素的个数 1 题目 2 算法原理 3 代码实现 493 翻转对
  • 八大排序(插入排序 | 选择排序 | 冒泡排序)

    在我们内存中我们一般会有一些没有顺序的数据 我们成为内排序 而今天分享八大排序的是时间复杂度为O N 2 的插入排序 选择排序和教学意义比较强的冒泡排序 插入排序 这是插入排序的动图 通过动图我们也是可以看到我们的插入排序的思想 从当前的位
  • 数组对象排序 (arr.sort())

    前端面试题库 面试必备 推荐 地址 前端面试题库 对象排序 arr sort 描述 方法sort 将在原数组上对 数组元素 进行排序 即排序时不创建新的数组副本 如果想按照别的顺序进行排序 就必须提供比较函数 该函数要比较两个值 然后返回一

随机推荐

  • Google BBR拥塞控制算法背后的数学解释

    杭州待了一段时间 回到深圳过国庆假期 无奈温州皮鞋 厂老板过节要回温州和上海 不在深圳 也就没有见着 非常遗憾 国庆节当天 就写这个了 经理不会弹琴 但是经理会弹琴 我原本可能会在想国庆节的凌晨到大清早写点什么呢 现在不用想了 就写BBR拥
  • 使用shell脚本更新文本数据至mysql数据库

    1 getgamedesc sh 功能 插入gamedesc txt文本中的 以 分割的第1列数据gid和第6列数据desc 到线网mysql数据库中 当字段 desc不为空时才执行插入 db param h127 0 0 1 uuser
  • qml文件之间的交互

    一 调用js函数 1 定义对方qml的id号 对方文件名要大写 2 KeyBoard qml定义js函数 3 自己的qml文件中进行调用 二 通过自定义属性的方式 1 本例使用子qml调用父qml 2 父id号 root 3 父qml文件中
  • 运维之道

    Docker 镜像使用 当运行容器时 使用的镜像如果在本地中不存在 docker 就会自动从 docker 镜像仓库中下载 默认是从 Docker Hub 公共镜像源下载 下面我们来学习 管理和使用本地 Docker 主机镜像 创建镜像 一
  • 高并发优化实战-连接数满载

    1 第三方http请求处理 finally httpclient getConnectionManager shutdown 2 linux服务器tcp处理 端口释放后的等待时间 默认为60s sysctl w net ipv4 tcp f
  • Vue2和Vue3的生命周期以及执行顺序

    前言 vue3现在是比较流行的 但是vue2的项目现在很多 而且我们会遇到把一部分vue2的项目移植到我们的vue3项目里面的情况 在这种情况下 如果我们熟悉vue2与vue3的生命周期顺序的话 对我们帮助是很大的 vue3生命周期的方法
  • php对接苹果cms采集接口,苹果cms的资讯采集api接口以及使用教程

    好多朋友都在说 想建个电影网站 电影资源大家都知道去某某影视资源网去找接口 蛋是这些资源网只有视频流媒体的网址 采集到的也是播放用的数据 那么苹果cms的资讯 以及演员是在哪里采集呢 那么请往下看 首先苹果cms的采集接口api是这种样子的
  • STP生成树协议与实验详解

    1 生成树协议概述 1 生成树协议简介 为了提高网络可靠性 交换网络中通常会使用冗余链路 然而 冗余链路会给交换网络带来环路风险 并导致广播风暴以及MAC地址表不稳定等问题 进而会影响到用户的通信质量 为了解决交换网络的环路问题 那么需要一
  • leetcode 934. 最短的桥(C++、python)

    在给定的二维二进制数组 A 中 存在两座岛 岛是由四面相连的 1 形成的一个最大组 现在 我们可以将 0 变为 1 以使两座岛连接起来 变成一座岛 返回必须翻转的 0 的最小数目 可以保证答案至少是 1 示例 1 输入 0 1 1 0 输出
  • 记录那些踩过的坑 - NSS error -5938 (PR_END_OF_FILE_ERROR), curl: (35) Encountered end of file

    PHP通过curl POST数据到https 同样的code 在第一个server上没有问题 在第二个server上却一直不成功 于是打开debug mode发现了下面的log code try 1 init curl ch curl in
  • Spring boot自定义切面拦截所有的请求 或者方法原理一样

    原代码 下面的例子是小编在自己的环境中测试过得 代码 Pointcut execution public com controller SysLoginController and execution public com controll
  • 卡内基梅隆大学计算机研究生水平,卡内基梅隆大学计算机研究生

    卡内基梅隆大学计算机研究生学位项目 立思辰留学云介绍 卡耐基梅隆大学计算机科学系 Computer Science Department 开设的研究生学位项目有 计算机科学博士 Ph D in Computer Science 授课地点在匹
  • [论文阅读] (26) 基于Excel可视化分析的论文实验图表绘制总结——以电影市场为例

    娜璋带你读论文 系列主要是督促自己阅读优秀论文及听取学术讲座 并分享给大家 希望您喜欢 由于作者的英文水平和学术能力不高 需要不断提升 所以还请大家批评指正 非常欢迎大家给我留言评论 学术路上期待与您前行 加油 前文详细介绍了向量表征系列文
  • mysql如何连接命令行_如何通过命令行连接mysql

    1 如何通过命令行连接mysql数据库 windows端 需要在命令行中进入mysql所在的目录下 进入bin目录下 比如我的路径是在 e tmallStudy mysql MySQL Server 5 7 bin下输入 mysql hlo
  • 华为OD机试真题- 快速开租建站【2023Q1】【JAVA、Python、C++】

    题目描述 当前IT部门支撑了子公司颗粒化业务 该部门需要实现为子公司快速开租建站的能力 建站是指在一个全新的环境部署一套IT服务 每个站点开站会由一系列部署任务项构成 每个任务项部署完成时间都是固定和相等的 设为1 部署任务项之间可能存在依
  • 机器学习算法——GBDT

    1 简介 GBDT全称梯度下降树 在传统机器学习算法里面是对真实分布拟合的最好的几种算法之一 在前几年深度学习还没有大行其道之前 gbdt在各种竞赛是大放异彩 原因大概有几个 一是效果确实挺不错 二是即可以用于分类也可以用于回归 三是可以筛
  • 【WIFI】WIFI-HT的意思

    HT40 使用40MHz频宽 但只支持1 7信道 HT40 使用40MHz频宽支持5 13信道 HT20 支持1 13信道 20MHz频宽 我们AP的802 11n默认是支持的 不需额外配置 如果radio设为11b 即是802 11ng
  • 五分钟了解JumpServer V3版本升级注意事项与平滑升级

    一 升级前数据梳理 1 账号 因 JumpServer V3 版本剔除了原本的系统用户功能 将资产与账号直接绑定 故升级前需保证每一台资产绑定的系统账号的用户名不重复 即每一个资产只可以保留一个同名账号 不可平滑升级示例 不可平滑升级的原因
  • 小程序的使用

    文件介绍 sitemap json 站点地图 微信搜一搜里面哪些页面可以展示 哪些不能 project config json 项目配置 app js 全局业务逻辑 app json 全局的小程序配置 app wxss 全局的样式 page
  • C++求行列式(满足一般性的解法)

    突发奇想对y总的模板进行如下应用 如有不当 还望斧正 由行列式的定义 不同行不同列的n个元素的乘积 当这个乘积列的下标的逆序对个数为偶数时 该项为正 当这个乘积列的下标的逆序对个数为奇数时 该项为负 那么我们需要写一个函数来求出这些数的逆序