首页 > 其他分享 >前缀和,二分 - [ABC203D] Pond

前缀和,二分 - [ABC203D] Pond

时间:2024-01-14 10:55:40浏览次数:24  
标签:ABC203D 前缀 int 矩阵 中位数 times MAXN Pond

AT_abc203_D Pond

题意

给出一个 \(N \times N\) 的矩阵,然后依次枚举 \(k \times k\) 的子矩阵。

对于 \(k \times k\) 的子矩阵,一共有个 \(k^2\) 元素,找出其中的中位数。这里的中位数是子矩阵中元素从大到小排列的第 $\left \lfloor \frac{k^2}{2} \right \rfloor $ 个元素。问对于所有子矩阵的中位数中,最小的那个中位数是多少。

思路

1. 暴力枚举

暴力枚举右下端点,将 \(k\times k\) 矩阵中的元素取出,然后排序。时间复杂度为 \(O(n^2k^2\log k)\),绝对超时。

2. 二分答案+二维前缀和

我们不妨转变思路,从枚举矩阵到二分中位数。判断一个值能否成为一个 \(k\times k\) 矩阵的中位数。

如何判断是否为中位数?

假设一个数 \(x\) ,如果 \(a_{i,j} > x\),那么另一个二维矩阵中的 \(b_{i,j}\) 便设为 \(1\),否则设为 \(0\)。这样便将矩阵 \(a\) 转变成了一个零一矩阵 \(b\)。对其求前缀和,这样就可以求得 \(b\) 中任意一个 \(k\times k\) 矩阵中 \(1\) 的个数。如果其中 \(1\) 的个数小于等于 $\left \lfloor \frac{k^2}{2} \right \rfloor $ 那么将上界调为 \(x\),否则将下界调整为 \(x+1\)。时间复杂度为 \(O(n^2\log n)\)。

Code

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 800 + 5;
int n, k, l, r, kpow, lim;
int a[MAXN][MAXN], b[MAXN][MAXN];
bool check(int x) {
	int z;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			b[i][j] = a[i][j] > x;//转化为01矩阵
			b[i][j] = b[i][j - 1] + b[i - 1][j] - b[i - 1][j - 1] + b[i][j];//求二维前缀和
		}
	}
	bool flag = 0;
	for (int i = 1; i <= n - k + 1; i++) {
		for (int j = 1; j <= n - k + 1; j++) {
			z = b[i + k - 1][j + k - 1] - b[i - 1][j + k - 1] - b[i + k - 1][j - 1] + b[i - 1][j - 1];//一的个数
			if (z <= kpow) {
				flag = 1;//如果找到了一个可能的值就退出
				break;
			}
		}
		if (flag) break;
	}
	return flag;
}
signed main() {
	scanf("%d%d", &n, &k);
	kpow = k * k / 2;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			scanf("%d", &a[i][j]);
			r = max(a[i][j], r);
		}
	}
	while (l < r) {//二分
		int mid = (l + r) >> 1;
		if (check(mid)) {//可行,找更小的
			r = mid;
		} else {
			l = mid + 1;
		}
	}
	printf("%d", r);
	return 0;
}

标签:ABC203D,前缀,int,矩阵,中位数,times,MAXN,Pond
From: https://www.cnblogs.com/Ice-lift/p/17963443

相关文章

  • Codeforces Round 918 (Div. 4) (前缀和,权值树状数组,二维偏序, python + golang)
    Dashboard-CodeforcesRound918(Div.4)-Codeforces  fromcollectionsimport*defsolve():a,b,c=list(map(int,input().split()))hs=defaultdict(int)hs[a]+=1hs[b]+=1hs[c]+=1foriinhs:ifhs[i]=......
  • check the manual that corresponds to your MySQL server version for the right syn
    form:{repairstatus:0,name:'',//负责人maintenancetime:newDate().toISOString().split('T')[0],//保修时间equipmentid:'',equipment:'',describe:'',finfishtime:'',repairname:'�......
  • Codeforces Round 918 (Div. 4)赛后总结(前缀和)(set部分用法)
    CodeforcesRound918(Div.4)赛后总结a,b题没啥好说的c题典中典没开longlong一回事,还有判断数a是否为完全平方数直接用sqrt(a)\(^2\)=a的判断就可以d题经典字符串问题首先,我们以一个字符数组的形式存数据。再根据已知cv,cvc两种形式,我们只需要判断c的时候看v是否有用过(可......
  • 如何利用搜索引擎指定网站(指定网址前缀)进行关键词搜索
    参考:site:搜索运算符博客园之前是有第三方搜索引擎(Google)的查询入口的,现在更新后就没有这个入口了,不过这也比较好理解,毕竟这个Google的查询入口好多人是用不了的,于是这里就给出手动指定查询网址的前缀来进行关键词查询了。例子:......
  • C++U4-第10课-前缀和与差分
    学习目标 前缀和解决的问题 前缀和概念 前缀和构建方式  前缀和主要解决区间求和问题练习题1:[前缀和]【算法分析】前缀和数组s的含义是s[i]表示a[1]~a[i]的和,那么∑i=li=r​a[i]=s[r]−s[l−1]。【参考代码】#include<iostream>usin......
  • mysql设计表名称要不要加表前缀
    在MySQL中设计表时,是否添加表前缀主要取决于你的具体需求和设计考虑。以下是一些关于是否使用表前缀的考虑因素:1,避免表名冲突:如果你的应用程序要与其他应用程序或系统共享数据库,或者你预计将来会有多个应用程序或系统使用同一个数据库,使用表前缀可以帮助避免表名冲突。例如,你......
  • 第 120 场双周赛(前缀和,双指针,树形dp+贪心)
     classSolution:deflargestPerimeter(self,nums:List[int])->int:nums.sort()n=len(nums)s=list(accumulate(nums))foriinrange(n-1,1,-1):ifnums[i]<s[i-1]:returnn......
  • 【力扣】-14. 最长公共前缀|刷题打卡-JS
    编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。示例1:输入:strs=["flower","flow","flight"]输出:"fl"示例2:输入:strs=["dog","racecar","car"]输出:""解释:输入不存在公共前缀。提示:1<=strs......
  • python 最长公共前缀 5种解法
    解法一:水平扫描这是最简单的一种方法,逐个字符比较每个字符串的相应位置,直到遇到不匹配的字符为止。deflongest_common_prefix(strs):ifnotstrs:return""prefix=strs[0]foriinrange(1,len(strs)):whilestrs[i].find(prefix)!=0:......
  • base64 常用的前缀
    .doc——data:application/msword;base64,.docx——data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,.xls——data:application/vnd.ms-excel;base64,.xlsx——data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet......