题目描述
Garfield小时候数学非常好,这与她喜欢数格子是分不开的。现在她有一张边长为N的方格纸(有若干破损),她想知道这张纸能够裁出多少矩形。
输入
第一行,一个整数N,表示方格纸的边长。
接下来N行,每行N个字符,字符0表示该位置完好,字符1表示该位置缺失。
输出
一个整数,表示裁出矩形的个数。
输入样例
3
000
010
010
输出样例
16
说明
对于50%的数据,N ≤ 20,
对于100%的数据,N ≤ 1000。
.
.
.
.
.
.
分析
单调栈
.
.
.
.
.
程序:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
char a[1010][1010];
stack<int>s;
int h[1010],up[1010][1010];
long long ans;
int main()
{
int n;
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%s",a[i]+1);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (a[i][j]=='0') up[i][j]=up[i-1][j]+1; else up[i][j]=0;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
long long w=0;
while (!s.empty()&&up[i][j]<up[i][s.top()])
{
ans+=(w*h[s.top()]+h[s.top()])*up[i][s.top()];
w+=h[s.top()];
s.pop();
}
s.push(j);
h[j]=w+1;
}
long long w=0;
while (!s.empty())
{
ans+=(w*h[s.top()]+h[s.top()])*up[i][s.top()];
w+=h[s.top()];
s.pop();
}
}
printf("%lld",ans);
return 0;
}