• 奶牛浴场


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

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

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

    答案是肯定的

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

    所以加入两个特判

    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群集安装
    iSCSI配置流程
    StarWind的安装配置
    安装SQL Server 2012 『企业中文版』
    计划安装SQL Server2012需求详细
    Max Degree of Parallelism最大并行度配置
    最佳的MongoDB客户端管理工具
    自学站点地图
    一个解决方案下多个项目时,怎么调试1个项目时不启动其他项目
    如何创建一个https的站点(超简单) 以及 IIS7.5绑定Https域名
  • 原文地址:https://www.cnblogs.com/coder-cjh/p/11622934.html
Copyright © 2020-2023  润新知