……

解题报告:luogu P1191

好久没更了,但这不代表不更了,是不是?
毕竟蒟蒻做蓝题需要时间
题目链接:P1191 矩形
抢到了第\(1000\)\(AC\)此题的荣耀。

一眼暴力,\(O(N^4)\),这不能过吧......
不管了,写上,\(AC\)
?这是啥情况,没有过\(10\;ms\)的点(虽然我卡了卡常)。
直接枚举一下左下角的坐标,然后枚举长宽,为了不用\(O(N^6)\)
我们前缀和优化一下吧。
\(S[i][j]\)表示从坐标为\((i,j)\)的点发出的最长的(向右)宽为\(1\)的矩形长。
不过不嫌麻烦可以写树状数组,复杂度\(O(N^4\log N)\),也是可以的。
题解区有大佬写了\(O(N^2)\),还是我太弱了。

\(Code\):

#include<iostream>
#include<cstdio>
#include<cmath>
#define R register
using namespace std;
const int MAXN=155;
int S[MAXN][MAXN]; 
long long ans=0;
int n;
char e[MAXN][MAXN];
inline void get()
{
	for(R int i=1;i<=n;i++)
	{
		int begin=0;
		for(R int j=1;j<=n+1;j++)
		{
			if(e[i][j]=='W'&&begin==0) begin=j;
			else if(e[i][j]=='B'&&begin!=0)
			{
				for(R int k=j-1;k>=begin;k--) S[i][k]=S[i][k+1]+1;
				begin=0;
			}
		}
	}
	return;
}
int main()
{
	scanf("%d",&n);
	for(R int i=1;i<=n;i++)
	{
		for(R int j=1;j<=n;j++)
		{
			cin>>e[i][j];
		}
	}
	for(R int i=1;i<=n;i++) e[i][n+1]='B';//处理一下
	get();
	for(R int i=1;i<=n;i++)
	{
		for(R int j=1;j<=n;j++)
		{
			for(R int k=1;k<=n-j+1;k++)
			{
				for(R int v=1;v<=i;v++)
				{
					if(S[i-v+1][j]<k) break;
					else
					{
						//printf("%d %d %d %d\n",i,j,i-v+1,j+k-1);
						ans++;
					}
				}
			}
		}
	}
	printf("%d\n",ans); 
	return 0;
}
posted @ 2020-03-12 18:52  童话镇里的星河  阅读(103)  评论(0编辑  收藏  举报