当前位置: 首页 > news >正文

学校网站怎么查询录取我的世界封面制作网站

学校网站怎么查询录取,我的世界封面制作网站,宁夏住宅建设发展公司网站,网页qq邮箱登录入口题目描述 从一个 N * M(N ≤ M)的矩阵中选出 N 个数,任意两个数字不能在同一行或同一列,求选出来的 N 个数中第 K 大的数字的最小值是多少。 输入描述: 输入矩阵要求:1 ≤ K ≤ N ≤ M ≤ 150 输入格式…

题目描述

从一个 N * M(N ≤ M)的矩阵中选出 N 个数,任意两个数字不能在同一行或同一列,求选出来的 N 个数中第 K 大的数字的最小值是多少。

输入描述:

输入矩阵要求:1 ≤ K ≤ N ≤ M ≤ 150

输入格式:

N M K

N*M矩阵

输出描述:

N*M 的矩阵中可以选出 M! / N! 种组合数组,每个组合数组种第 K 大的数中的最小值。无需考虑重复数字,直接取字典排序结果即可。

备注:

注意:结果是第 K 大的数字的最小值

示例1:

输入:

3 4 2
1 5 6 6
8 3 4 3
6 8 6 3
输出:

3

说明:

N*M的矩阵中可以选出 M!/ N!种组合数组,每个组合数组种第 K 大的数中的最小值;

上述输入中选出数组组合为:

1,3,6;

1,3,3;

1,4,8;

1,4,3;

......

上述输入样例中选出的组合数组有24种,最小数组为1,3,3,则第2大的最小值为3

题解

根据要求,每行每列只能有一个元素被选择,即可以认为每个行号只能和一个列号进行配对,且配对过的列号不能再和其他行号配对,而形成了配对关系的行号,列号,其实就是一个元素的坐标位置。

因此,找N个互相不同行同列的元素,其实就是在二分图(所有行号一部分,所有列号一部分)找N个边的匹配。

如下图所示

关于二分图的知识可以看下:

HDU - 2063 过山车(Java & JS & Python & C)-CSDN博客

题目需要我们多组N个元素中的第K大元素的最小取值,

换位思考一下,假设我们已经知道了第K大的最小取值是kth,那么:

  • 检查矩阵中是否至多找到(N - K + 1 个) ≤ kth 的元素值,且这些元素值互不同行同列

N个数中,有K-1个数比kth大,那么相对应的有 (N - (K-1)) = (N - K + 1 ) 个数 ≤ kth。

即找的 N - K + 1 个数中包含了 kth(第K大值)本身。

而kth的大小和二分图最大匹配是正相关的,因为:

每个匹配边 其实就是 行号到列号的配对连线

而行号和列号的组合其实就是坐标位置,根据坐标位置可以得到一个矩阵元素值

因此kth越小,意味着可以找到的 ≤ kth 的矩阵元素越少,相反的,kth 越大,则找到的 ≤ kth 的矩阵元素越多。

因此kth值大小和二分图最大匹配数是线性关系,我们可以使用二分法,来枚举kth。

二分枚举的范围是:1 ~ 矩阵元素最大值,这里不用担心二分枚举到kth不是矩阵元素,因为这种情况会被过滤掉,原因是:我们要找 N - K + 1 个 <= kth 的矩阵元素,最后把关的必然是 kth 本身,即我们必然要在矩阵中找到一个 kth 值,如果二分枚举到的 kth 不是矩阵元素,则无法满足这个要求。

二分枚举到一个kth值:

  • 如果kth使得二分图最大匹配 >= N-K+1 个,则说明当前kth取大了,我们应该尝试更小的kth值,即缩小二分右边界为kth-1
  • 如果kth使得二分图最大匹配 < N-K+1 个,则说明当前kth取小了,我们应该继续尝试更大的kth值,即扩大二分左边界为kth+1

当二分左右边界重合时的kth值即为题解。

import java.util.Arrays;
import java.util.Scanner;public class Main {static int n;static int m;static int k;static int[][] matrix;public static void main(String[] args) {Scanner sc = new Scanner(System.in);n = sc.nextInt();m = sc.nextInt();k = sc.nextInt();int min = 1;int max = Integer.MIN_VALUE;matrix = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {matrix[i][j] = sc.nextInt();max = Math.max(max, matrix[i][j]);}}// 二分枚举第K大值while (min <= max) {// mid就是被枚举出来的N个数中的第K大值int mid = (min + max) >> 1;// 检查mid作为N个数中第K大值时,是否存在N-K+1个不大于它的值if (check(mid)) {max = mid - 1;} else {min = mid + 1;}}System.out.println(min);}public static boolean check(int kth) {// 利用二分图最大匹配来求解,小于等于kth(第K大值)的元素个数(即二分图最大匹配)int smallerCount = 0;// 记录每个列号的匹配成功的行号int[] match = new int[m];// 初始时每个列号都处于未配对状态,此时将列号配对的行号赋值为-1Arrays.fill(match, -1);// 遍历行号,每个行号对互相心仪的列号发起配对请求for (int i = 0; i < n; i++) {// 记录增广路访问过的列号boolean[] vis = new boolean[m];if (dfs(i, kth, match, vis)) smallerCount++;}return smallerCount >= n - k + 1;}public static boolean dfs(int i, int kth, int[] match, boolean[] vis) {// 行号 i 发起了配对请求// 遍历每一个列号jfor (int j = 0; j < m; j++) {// 如果当前列号j未被增广路探索过 && 当前列j行i可以配对(如果行列号位置(i,j)对应矩阵元素值小于等于kth(第K大值),则可以配对)if (!vis[j] && matrix[i][j] <= kth) {vis[j] = true;// 如果对应列号j未配对,或者,已配对但是配对的行号match[j]可以找到其他列号重新配对if (match[j] == -1 || dfs(match[j], kth, match, vis)) {// 则当前行号i 和 列号j 可以配对match[j] = i;return true;}}}return false;}
}
http://www.dtcms.com/a/517664.html

相关文章:

  • 用文件传输协议登录网站wordpress读取产品数据库
  • 网站建设销售简历网站同时做竞价和seo
  • 湘潭市哪里做网站wordpress防破解
  • h5商城网站怎么建设编程网址
  • 网站建设的工作群晖wordpress二级目录
  • 北京网站建设116net东莞做网页设计
  • 德国 网站后缀怎么制作免费网站
  • 计算机算法分类及区别详解
  • 电子商务网站规划设计包括哪些方面搜索李晓峰
  • 建设协会官方网站做网站需要每年都交钱吗
  • 看会员视频的网站开发做网站的公司叫什么
  • [手写系列]Go手写db — — 第六版(实现表连接)
  • 如何分辨动态公网ip和固定公网ip之间的关系有什么不同?
  • 靖边县建设局网站安徽阜阳网站建设
  • 高校网站建设 安全教育龙岩注册公司
  • 淘宝网那样的网站模板图片上的字体导入wordpress
  • 优度公司做的网站在线教育类网站模板
  • 太原企业网站制作公司聊城做网站的公司价格
  • Springboot | 初识Springboot 从“手动做饭”到“点外卖”的编程革命
  • 网站建设高凯里市住房和城乡建设局网站
  • 做网站需要了解哪些知识做餐饮要看的网站
  • 广东广州电脑个人建站排版设计技巧
  • 网站做的好看的山东ui设计培训班
  • 做网站的得花多少钱织梦 网站公告
  • 证券公司网站建设方案靖江网站优化
  • 游戏网站做关键字百度一下你就知道移动官网
  • 四川省城乡和建设厅网站做团购的家居网站有哪些
  • 购物网站开发的背景和意义做网站的公司怎么做抖音账号
  • 扬州市城乡建设局网站西安360免费做网站
  • 照片做视频的软件 模板下载网站好学做视频t的网站