金牌厨师HiLin与HJGG(二维前缀 + 二分!)

原题链接:https://ac.nowcoder.com/acm/contest/3570/L在这里插入图片描述
在这里插入图片描述

分析:一看题目,求矩形中所有值的和,差不多就是二维前缀和。但是,如果简单的用二维前缀和遍历每一个点,每一个边长,超时!
接着,我们看,这个边长是可以二分的!
具备二分的条件:区间具有单调性!边长越大,求出的矩阵所有值的和越大!
于是,我们就二分边长!

这样,将遍历边长的复杂度O(n)降低为O(log n)!
总复杂度:O(n * n * log n)

code:

#include<iostream>
using namespace std;

const int N=2010;
long long a[N][N],n,sum;
int ans=1e9;

int main(){
	cin>>n>>sum;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			scanf("%lld",&a[i][j]); //输入过多,用scanf 
			a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1]; //求二位前缀 
		}
	}
	
	//对每个位置,二分矩形(正方形)的边长 
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			int l=0,r=min(n-i,n-j); //以该位置为左上角,增加的边长长度 
			while(l<r)
			{
				int mid=l+r>>1;
				if(a[i+mid][j+mid]-a[i-1][j+mid]-a[i+mid][j-1]+a[i-1][j-1]>=sum) r=mid; 
				//二位前缀,求以(i,j)为左上角,以(i+mid,l+mid)为右下角的矩形中所有值的和,大于等于目标值,说明边长偏大 
				else l=mid+1;
			}
			if(a[i+l][j+l]-a[i-1][j+l]-a[i+l][j-1]+a[i-1][j-1]>=sum){ //检查是否找到 
				ans=min(ans,l);
			}
		}
	}
	if(ans!=1e9) cout<<ans+1;
	else cout<<"I'm a Gold Chef!";
	return 0;
} 

如果对 二维前缀和二分 不太熟的话,可以看我的两个博客(前缀和&差分二分查找&二分答案)专门讲这两个知识点!

如果有问题的话,欢迎留言评论!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值