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

奶牛浴场

时间:2019-10-04 21:01:04      阅读:109      评论:0      收藏:0      [点我收藏+]

标签:悬线法   扫描   代码   define   col   can   价值   space   min   

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

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

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

答案是肯定的

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

所以加入两个特判

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 node{int 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);
}

 

奶牛浴场

标签:悬线法   扫描   代码   define   col   can   价值   space   min   

原文地址:https://www.cnblogs.com/coder-cjh/p/11622934.html

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