51nod 矩形的数量V9
作者:互联网
http://www.51nod.com/Contest/Problem.html#contestProblemId=4864
题面
在 m∗n 的方格中,有一些格子被涂了色。现在请问整个图形中,共能找出 完全涂了色 的不同形状的矩形分别有多少个?
输入
第一行输入两个数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
样例解释
样例中的图形如上所示,其中2、3、4、5、7、8号格子涂了色。
因此完全涂色的矩形有:
11:2、3、4、5、7、8,共6个;
21:25、47、58,共3个;
3*1:258,共1个;
12:23、45、78,共3个;
22:4578,共1个;
3*2:无;
13:无;
23:无;
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