ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

51nod 矩形的数量V9

2022-07-22 16:36:10  阅读:131  来源: 互联网

标签:605 ch 51nod pos int 涂色 ans 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有