码迷,mamicode.com
首页 > 其他好文 > 详细

【刷题】【垂线法】

时间:2019-10-23 22:31:01      阅读:78      评论:0      收藏:0      [点我收藏+]

标签:bsp   return   namespace   view   都对   mat   main   ide   组成   

(luogu)

悬线的定义是这样的:

从每一个点向上走,知道遇到障碍点或顶边界。

那么我们可以轻松地得到悬线的一些性质:

  1. 每一个点对应一根悬线
  2. 每一根悬线都对应了一个高度等于悬线高度,宽度大于0的矩形

所以悬线法的步骤就是:找出每一个点对应的悬线的高度,然后向左右分别找出该悬线能拓展出的矩形的宽度。

 

题面:

小Q找到了一张由N×M个正方形的格子组成的矩形纸片,每个格子被涂有黑白两种颜色之一。

小Q想在这种纸中裁减一部分作为新棋盘,当然,他希望这个棋盘尽可能的大。

当然,不管哪种,棋盘必须都黑白相间,即相邻的格子不同色,

所以他希望可以找到最大的正方形棋盘面积和最大的矩形棋盘面积,从而决定哪个更好一些。

 

棋盘制作

技术图片
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int n,m;
const int N=2003;
int d[N][N];
int ll[N][N],rr[N][N],up[N][N];

int main()
{
    //输入 
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%d",&d[i][j]),
            up[i][j]=1,ll[i][j]=rr[i][j]=j;
    //悬线法 
    
    for(int i=1;i<=n;i++)
        for(int j=2;j<=m;j++)
            if(d[i][j]^d[i][j-1]) 
                ll[i][j]=ll[i][j-1];
    for(int i=1;i<=n;i++)
        for(int j=m-1;j;j--)
            if(d[i][j]^d[i][j+1]) 
                rr[i][j]=rr[i][j+1];
    for(int j=1;j<=m;j++)
        for(int i=2;i<=n;i++)
            if(d[i][j]^d[i-1][j]) 
                up[i][j]=up[i-1][j]+1,
                ll[i][j]=max(ll[i][j],ll[i-1][j]),
                rr[i][j]=min(rr[i][j],rr[i-1][j]);
    //统计答案 
    int s1=0,s2=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            int len=rr[i][j]-ll[i][j]+1;
            s1=max(s1,min(len,up[i][j]));
            s2=max(s2,len*up[i][j]);
        }
    printf("%d\n%d\n",s1*s1,s2);
    return 0;
}
View Code

 

【刷题】【垂线法】

标签:bsp   return   namespace   view   都对   mat   main   ide   组成   

原文地址:https://www.cnblogs.com/xwww666666/p/11729033.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!