题目大意
教主上电视了!这个消息绝对是一个爆炸性的新闻。一经传开,大街上瞬间就没人了(都回家看电视去了),商店打烊,工厂停业。大家都把电视机的音量开到最大,教主的声音回响在大街小巷。
小L给小X慌乱地打开自己家的电视机,发现所有频道都播放的是教主的采访节目(-_-bbb)。只见电视屏幕上的教主笑意吟吟,给大家出了一道难题:
一个边长为n的大菱形被均匀地划分成了n*n个边长为1的小菱形组成的网格,但是网格中部分边被抹去了,小L想知道,大菱形内有多少个平行四边形,这些平行四边形内不存在边。
教主说,如果谁写出了程序,移动用户请将程序发送到xxxx,联通用户请将程序发送到xxxx……如果答对这个题,将有机会参加抽奖,大奖将是教主签名的Orz教主T-Shirt一件!这个奖品太具有诱惑力了。于是你需要编一个程序完成这么一道题。
分析
首先将在读入时将菱形转成正方形。(自己推)
有(n+1)*(n+1)个格点,用d[i][j]表示第i行第j列的格点到第1行第j列的格点之间有多少条竖线,f[i][j]表示第i行第j条横线(被抹去的也算)在这一列上的上一条没被抹去横线的位置。
接着扫描i,j。
设h为矩形的高,初值为-1。若第i行第j根横线没被抹去,且d[i][j]-d[i-f[i][j]][j]=f[i][j]即当前横线到上一根横线的左边有封闭的竖线,那么表示这可能是一个矩形的开始,此时矩形的高h赋为f[i][j]。
若h>-1,且d[i][j]-d [i-h][j]>0即当前扫描到的段左边有若干条竖线(矩形内不为空);或f[i][j]<>h(矩形内不为空或不是矩形);或当前扫描到的横线被抹去,h赋为-1。
若h>-1且d[i][j+1]-d[i-h][j+1]=h,即横线右边线段有封闭的竖线,那么答案+1。
ps:注意细节!!!
code
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
char a[2000][2000];
int f[2000][2000];
int d[2000][2000];
int h[2000][2000];
int n;
int init()
{
scanf("%d",&n);
int jj=n;
for (int i=1;i<=2*n;i++)
{
char c=getchar();
for (int j=1;j<=2*n;j++)
scanf("%c",&a[i][j]);
}
int x=1;
int y=n;
for (int i=1;i<=n+1;i++)
{
int xx=x;
for (int j=2;j<=n+n;j+=2)
{
if (a[x][y]=='/')
f[j][i]=1;
x++;
y--;
}
x=xx+1;
y=n+i;
}
x=1;
y=n+1;
int ii=1;
for (int i=1;i<=n+n+1;i+=2)
{
int xx=x;
for (int j=1;j<=n;j++)
{
if (a[x][y]!=' ')
f[i][j]=2;
x++;
y++;
}
x=xx+1;
y=n-ii+1;
ii++;
}
x=1;
for (int i=1;i<=n+n+1;i+=2)
{
int y=1;
for (int j=1;j<=n+1;j++)
{
if (f[i-1][j]==1)
d[x][y]=d[x-1][y]+1;
else
d[x][y]=d[x-1][y];
if (f[i-2][j]==2)
h[x][y]=x-1;
else
h[x][y]=h[x-1][y];
y++;
}
x++;
}
for (int j=1;j<=n+1;j++)
{
h[n+2][j]=n+1;
}
}
int main()
{
init();
int hmax=-1;
int ans=0;
for (int i=2;i<=n+1;i++)
for (int j=1;j<=n+1;j++)
{
if (h[i+1][j]!=i)
{
hmax=-1;
continue;
}
if (hmax==-1)
{
if ((i-h[i][j])==(d[i][j]-d[h[i][j]][j]))
hmax=i-h[i][j];
if (hmax==(d[i][j+1]-d[h[i][j]][j+1]))
{
ans++;
}
continue;
}
else
{
if ((d[i][j]-d[h[i][j]][j])>0)
hmax=-1;
if ((i-h[i][j])!=hmax)
hmax=-1;
if (hmax==-1)
if ((i-h[i][j])==(d[i][j]-d[h[i][j]][j]))
hmax=i-h[i][j];
if (hmax==(d[i][j+1]-d[h[i][j]][j+1]))
{
ans++;
continue;
}
}
}
printf("%d",ans);
}