P7715 「EZEC-10」Shape 题解

题面

P7715 「EZEC-10」Shape

思路

记录每个白点向上,向下,向右拓展距离的最大值,枚举每个H的左边的T字形交叉点,取向右拓展的一段白点的min(向上拓展距离,向下拓展距离),从小到大排序,较短的都对较大的有贡献

易错点

  1. 注意审题!!!H只能竖着,不能横着
  2. H的两条竖杠可以相邻

code

#include<bits/stdc++.h>
#define int long long
#define N 2010
#define re register 
using namespace std;
int n,m,ans,b[N][N],r[N][N],u[N][N],d[N][N],c[N],cnt;
template <class T> inline void read(T &x)
{
	x=0;int g=1;char s=getchar();
	for (;s<'0'||s>'9';s=getchar()) if (s=='-') g=-1;
	for (;s>='0'&&s<='9';s=getchar()) x=(x<<1)+(x<<3)+(s^48);
	x*=g;
}
signed main()
{
	re int i,j,x,y,z,op,k;
	read(n);read(m);
 	for (i=1;i<=n;i++) for (j=1;j<=m;j++) read(b[i][j]);
 	for (i=1;i<=n;i++)
 	{
 		int p;
		for (j=m;j;j--)
		if (!b[i][j])
 		{
 			if (j==m||b[i][j+1]==1) p=j;
 			r[i][j]=p-j+1;
		}
	}
 	for (i=1;i<=m;i++)
 	{
 		int p;
 		for (j=1;j<=n;j++)
 		if (!b[j][i])
 		{
 			if (j==1||b[j-1][i]==1) p=j;
 			u[j][i]=j-p+1;
		}
		for (j=n;j;j--)
		if (!b[j][i])
 		{
 			if (j==n||b[j+1][i]==1) p=j;
 			d[j][i]=p-j+1;
		}
	}
	for (i=2;i<n;i++)
	{
		for (j=1;j<m;j++)
		if (!b[i][j]) 
		{
			if (u[i][j]>=2&&d[i][j]>=2&&r[i][j]>=2)
			{
				cnt=0;
				for (k=j;k<=j+r[i][j]-1;k++)
				{
					int tmp=min(u[i][k],d[i][k])-1;
					if (tmp>0 )c[++cnt]=tmp;
				}
				sort(c+1,c+cnt+1);
				for (k=1;k<=cnt;k++)
					ans+=(cnt-k)*c[k];
				for (k=1;k<=cnt;k++) c[k]=0;
				j=j+r[i][j]-1;
			}
		}
	}
	printf("%lld
",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/Ritalc/p/15017811.html