• 奶牛浴场


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

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

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

    答案是肯定的

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

    所以加入两个特判

    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
    ",ans);
    }
  • 相关阅读:
    windows查询占用端口的pid以及查询对应的进程名称
    [转]Android学习系列(29)App调试的几个命令实践
    [原]Android中接入微信客户端心得
    Robots.txt使用指南
    SqlHelper中使用事务
    QQ 影音,功能手札
    Access 2007数据库压缩和修复数据库功能
    dhl:PetShop里面的sqlHelper相关操作
    dhl:svn客户端学习TortoiseSVN的基本使用方法
    从 if else 到设计模式的转变
  • 原文地址:https://www.cnblogs.com/coder-cjh/p/11622934.html
Copyright © 2020-2023  润新知