CF1731D Valiant‘s New Map 题解

CF1731D Valiant’s New Map 题解

link

Valiant’s New Map

题面翻译

给定一个带权值的 n × m n×m n×m 网格,你可以选取一块边长为 l l l 的正方形区域当且仅当该区域的所有权值都大于等于 l l l,问可以选取的最大正方形区域的边长。

题目描述

Game studio “DbZ Games” wants to introduce another map in their popular game “Valiant”. This time, the map named “Panvel” will be based on the city of Mumbai.

Mumbai can be represented as n × m n \times m n×m cellular grid. Each cell ( i , j ) (i, j) (i,j) ( 1 ≤ i ≤ n 1 \le i \le n 1in ; 1 ≤ j ≤ m 1 \le j \le m 1jm ) of the grid is occupied by a cuboid building of height a i , j a_{i,j} ai,j .

This time, DbZ Games want to make a map that has perfect vertical gameplay. That’s why they want to choose an l × l l \times l l×l square inside Mumbai, such that each building inside the square has a height of at least l l l .

Can you help DbZ Games find such a square of the maximum possible size l l l ?

输入格式

Each test contains multiple test cases. The first line contains the number of test cases t t t ( 1 ≤ t ≤ 1000 1 \leq t \leq 1000 1t1000 ). Description of the test cases follows.

The first line of each test case contains two positive integers n n n and m m m ( 1 ≤ n ≤ m 1 \le n \le m 1nm ; 1 ≤ n ⋅ m ≤ 1 0 6 1 \leq n \cdot m \leq 10^6 1nm106 ).

The $ i $ -th of next n n n lines contains m m m integers a i , 1 , a i , 2 , … , a i , m a_{i,1}, a_{i,2}, \dots, a_{i,m} ai,1,ai,2,,ai,m ( 1 ≤ a i , j ≤ 1 0 6 1 \leq a_{i,j} \leq 10^6 1ai,j106 ) — heights of buildings on the i i i -th row.

It’s guaranteed that the sum of n ⋅ m n \cdot m nm over all test cases doesn’t exceed 1 0 6 10^6 106 .

输出格式

For each test case, print the maximum side length l l l of the square DbZ Games can choose.

样例 #1

样例输入 #1

4
2 2
2 3
4 5
1 3
1 2 3
2 3
4 4 3
2 1 4
5 6
1 9 4 6 5 8
10 9 5 8 11 6
24 42 32 8 11 1
23 1 9 69 13 3
13 22 60 12 14 17

样例输出 #1

2
1
1
3

提示

In the first test case, we can choose the square of side l = 2 l = 2 l=2 (i. e. the whole grid) since the heights of all buildings are greater than or equal to 2 2 2 .

In the second test case, we can only choose the side as 1 1 1 , so the answer is 1 1 1 .

In the third test case, there are no squares of size 2 2 2 that have all buildings of height at least 2 2 2 , so the answer is 1 1 1 .

算法:二分+二维前缀和

思路:用二维前缀和数组来存储是否符合条件。

考虑在一个矩阵中,如何计算从 ( 1 , 1 ) ( 1 , 1 ) (1,1) ( x , y ) ( x , y ) (x,y) 这一部分的和呢?可以用 f i , j f_{i,j} fi,j 表示从 ( 1 , 1 ) ( 1 , 1 ) (1,1) ( i , j ) ( i ,j ) (i,j) 的总和,则 f i , j ← f i − 1 , j + f i , j − 1 − f i − 1 , j − 1 + a i , j f_{i,j} \gets f_{i-1,j} + f_{i,j-1} - f_{i-1,j-1} + a_{i,j} fi,jfi1,j+fi,j1fi1,j1+ai,j,中间之所以要减去是因为重复计算了。

因为并不确定 n n n m m m 的值,所以要用 vector,注意要先动态开空间之后才能当作数组使用。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=1e6+10;
ll T,n,m,ans,t,l,r,mid;
vector<ll> a[N],f[N];
bool check(ll p){
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			f[i][j]=a[i][j]<mid;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			f[i][j]+=f[i-1][j]+f[i][j-1]-f[i-1][j-1];
	for(int i=1;i+p<=n;i++)
		for(int j=1;j+p<=m;j++)
			if(!(f[i+p][j+p]+f[i-1][j-1]-f[i-1][j+p]-f[i+p][j-1]))
				return 1;
	return 0;
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    cin>>T;
    while(T--){
		cin>>n>>m;
		f[0].clear();
		for(int i=0;i<=m;i++) f[0].push_back(0);		
		for(int i=1;i<=n;i++){
			a[i].clear();
			a[i].push_back(0);
			f[i].clear();
			f[i].push_back(0);
			for(int j=1;j<=m;j++){
				cin>>t;
				a[i].push_back(t);
				f[i].push_back(0);
			}
		}
		l=1,r=n;
		while(l<=r){
			mid=l+r>>1;
			if(check(mid-1)) l=mid+1,ans=mid;
			else r=mid-1;
		}
		cout<<ans<<"\n";
    }
	return 0;
}

  • 22
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值