奶牛浴场

Posted coder-cjh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了奶牛浴场相关的知识,希望对你有一定的参考价值。

这道题我用了扫描法,悬线法还没有填坑

首先想到尽量减少枚举量,也就是尽量让每个矩形都是有意义的,那么只有障碍点边缘有价值,所以只需要从左到右扫描一遍,得到的全部都是有意义的。

那么这种方法是否还有遗漏呢?

答案是肯定的

因为我们从左到右搜,肯定是以左边为准线,那么如果一直延伸到右边,那么如果是右边延伸到左边就会遗漏,同理,如果与左边界和右边界重合的矩形也会遗漏。

所以加入两个特判

1.从右边扫一遍,特判第一种情况

2.从上到下排序,相邻的两个点*横轴就是第二种情况

详细见代码

#include<bits/stdc++.h>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
using namespace std;
int r,c,n,ans;
struct nodeint x,y;a[5050];
bool cmp(node a,node b)return a.x<b.x;
bool cmp1(node a,node b)return a.y<b.y;
int main()
    scanf("%d%d%d",&r,&c,&n);
    for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
    a[++n].x=0;a[n].y=c;//注意的细节,为了方便处理
    a[++n].x=0;a[n].y=0;//在矩形边界都设置了障碍点
    a[++n].x=r;a[n].y=c; 
    a[++n].x=r;a[n].y=0;
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++)//开始扫描
     int up=0,dn=c,v=a[i].x;
     for(int j=i+1;j<=n;j++)//从左到右
        ans=max(ans,(a[j].x-a[i].x)*(dn-up));//能延伸的最大子矩阵
        if(a[i].y==a[j].y)break;
        if(a[j].y>a[i].y)dn=min(dn,a[j].y);//修改上下边界
        else up=max(up,a[j].y);
     
     up=0;dn=c;v=r-a[i].x;
     for(int j=i-1;j;j--)//从右到左
        ans=max(ans,(a[i].x-a[j].x)*(dn-up));
        if(a[i].y==a[j].y)break;
        if(a[j].y>a[i].y)dn=min(dn,a[j].y);
        else up=max(up,a[j].y);
     
    
    sort(a+1,a+n+1,cmp1);
    for(int i=1;i<n;i++)ans=max(ans,(a[i+1].y-a[i].y)*r);//特判第二种情况
    printf("%d\n",ans);

 

以上是关于奶牛浴场的主要内容,如果未能解决你的问题,请参考以下文章

P1578 奶牛浴场

洛谷1578:[WC2002]奶牛浴场——题解

[WC2002][洛谷P1578]奶牛浴场

奶牛浴场,最大子矩阵

Vijos 1055 奶牛浴场

奶牛浴场