牛客 2019暑假多校比赛 第二场 H_Second Large Rectangle

本文介绍了一种求解给定01矩阵中第二大全1矩阵面积的方法。通过预处理每列1的数量,并利用并查集维护连通区域的最大长度,结合排序技巧找到满足条件的矩阵。最终输出第二大的矩阵面积。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门;

题目大意:

给定一个n*m的只含0 1的矩阵,求第二大全1的矩阵面积

输入样例

1 2
01

输出

0

输入

1 3
101

输出

1


求第二大的全1矩阵,首先要确定怎么求每个矩阵,我们确定每一列上的1,如果当前列有1,那么我们把下面一行的对应列上的1+1;如

0001
0011
0011
0000

就可以预先处理成

0001
0012
0023
0000

每个数字表示这之上还有几个1,这样过会就可以对列进行排序,从而找到1最多的那个列,因为是最多的列1先找到,那么剩下相邻列如果也有1,那么一定比这列小,这样总是可以组成小的列上的矩形,长度用并查集来维护,这样每次相邻的位置都可以找到长度能够到最大延申的位置;然后我们需要找到第二大的矩形,那么第二大满足矩形的什么条件呢,事实上我们只需要找到各个不在同一连通里矩形和在每个连通里矩形外围扣一个点,这样就会变成找每个独立连通的矩形和这个矩形的长-1或者宽-1,只保存最大和第二大,最后输出第二大即可。

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define F first
#define S second
typedef pair<int,int> p;
int n,m,maxa,maxb;
char s[1010];
int a[1010][1010],t[1010][1010];
int vis[1010],sz[1010],pre[1010];
p h[1010];
void read(){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++){
		cin >> s+1;
		for(int j=1;j<=m;j++) 
		a[i][j]=(s[j]=='0')?0:1;
	}
}
void work1(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			t[i][j]=(a[i][j]==1)?t[i-1][j]+1:0; //预处理每列1 
		}
	}
}
int ffind(int x){
	return x==pre[x]?x:pre[x]=ffind(pre[x]); //并查集维护最大长度 
}
void _union(int x,int y){
	pre[y]=x;
	sz[x]+=sz[y];   
}
void work(int x){ //只保存最大和第二大 
	if(x>maxa) maxb=maxa,maxa=x;
	else if(x>maxb) maxb = x;
}
int main(){
	read();
	work1();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++) pre[j]=j,sz[j]=1,vis[j]=0,h[j]=(p){t[i][j],j};  
		sort(h+1,h+m+1);
		for(int j=m;j;j--){
			int x=h[j].S;
			vis[x]=1;
			if(vis[x-1]) _union(ffind(x),ffind(x-1));//如果当前大小点的左右两边有之前被遍历过的,那么就满足大边必定满足小边 
			if(vis[x+1]) _union(ffind(x),ffind(x+1));
			int len = sz[ffind(x)];
			work(len*h[j].F); //这里找第二大的,只需要扣一个点下来即可, xy,x(y-1),(x-1)y 
			work(len*(h[j].F-1)); 
			work((len-1)*h[j].F);
		}
	}
	cout<<maxb<<endl;
	return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值