其他分享
首页 > 其他分享> > 51nod 矩形的数量V9

51nod 矩形的数量V9

作者:互联网

http://www.51nod.com/Contest/Problem.html#contestProblemId=4864

题面

在 m∗n 的方格中,有一些格子被涂了色。现在请问整个图形中,共能找出 完全涂了色 的不同形状的矩形分别有多少个?

image

输入
第一行输入两个数m,n,分别表示方格的列数、行数;(1<=m,n<=600)
之后n行,每行一个m个字符组成的01串描述方格的涂色情况。其中1表示涂了色,0表示未涂色。
输出
输出共n行, 每行m个数以空格隔开,其中第i行第j个数表示占据i行j列的完全涂色矩形的数量。
输入样例
3 3
011
110
110
输出样例
6 3 0
3 1 0
1 0 0
样例解释

image

样例中的图形如上所示,其中2、3、4、5、7、8号格子涂了色。

因此完全涂色的矩形有:

11:2、3、4、5、7、8,共6个;
2
1:25、47、58,共3个;
3*1:258,共1个;

12:23、45、78,共3个;
2
2:4578,共1个;
3*2:无;

13:无;
2
3:无;
3*3:无。


赛时自己能做出来还是比较符合期望的。

悬线法,从暴力->记录向上最多能多少->悬线法,枚举向上的个数,然后找当前这个位置向左最多能扩展多少->大的一定能贡献小的->后缀和。

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
int rd() {
	int f=1,sum=0; char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)) {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
	return sum*f;
}

void pr(int x) {
	if(x<0) {putchar('-');x=-x;}
	if(x>9) pr(x/10);
	putchar(x%10+'0');
}
char s[605];
bool e[605][605];
int n,m,ans[605][605],up[605][605],L[605][605];

signed main() {
	m=rd(); n=rd();
	for(int i=1;i<=n;i++) {
		for(int j=1;j<=m;j++) {
			char ch=getchar();
			while(!isdigit(ch)) ch=getchar();
			e[i][j]=ch-'0';
		}
	}
	for(int i=1;i<=n;i++) {
		for(int j=1;j<=m;j++) {
			if(e[i][j]) up[i][j]=up[i-1][j]+1;
		}
	}
	memset(L,0x3f,sizeof(L));
	for(int i=1;i<=n;i++) {
//		memset(st,0x3f,sizeof(st));
//		for(int j=1;j<=m;j++) st[0][j]=up[i][j];
//		for(int j=1;(1<<j)<=m;j++)
//			for(int k=1;k+(1<<j)-1<=m;k++)
//				st[j][k]=min(st[j-1][k],st[j-1][k+(1<<(j-1))]);
		for(int j=1;j<=m;j++) {
//			L[i][j]=min(L[i][j-1],)
			if(!e[i][j]) continue ;
			for(int x=1;x<=i;x++) {
				if(up[i][j]>=x) {
					L[j][x]=j;
//					cout<<i<<" "<<j<<endl;
				} else {
					break ;
				}
				if(j>1&&e[i][j-1]) L[j][x]=min(L[j][x],L[j-1][x]);
//				cout<<i<<" "<<j<<" "<<x<<" "<<L[i][j][x]<<" "<<up[i][j]<<'\n';
				if(L[j][x]) ++ans[x][j-L[j][x]+1];
//				int pos=0;
//				int l=1,r=j;
//				while(l<=r) {
//					int mid=(l+r)>>1;
//					if(get(mid,j)>=x) pos=mid,r=mid-1; else l=mid+1;
//				}
//				if(!pos) break ;
//				++ans[x][j-pos+1];
//				int pos=0;
//				for(int k=j;k>=1;k--) {
//					if(up[i][k]>=x) pos=k;
//					else break ;
//				}
//				if(!pos) break ;
//				ans[x][j-pos+1]++;
			}
		}
		memset(L,0x3f,sizeof(L));
	}
	for(int i=1;i<=n;i++) {
		int qwq=ans[i][m];
		for(int j=m-1;j>=1;j--) {
			qwq+=ans[i][j]; 
			ans[i][j]=qwq;
		}
	}
	for(int i=1;i<=n;i++) {
		for(int j=1;j<=m;j++) {
			pr(ans[i][j]); putchar(' ');
		} putchar('\n');
	}
	return 0;
}	

标签:605,ch,51nod,pos,int,涂色,ans,V9,矩形
来源: https://www.cnblogs.com/xugangfan/p/16506182.html