• 扫描线与悬线


    好像很水....

    但我就是想不到QAQ.......

     

     

    AC VIJOS 1055 奶牛浴场

      1 #include <cstdio>
      2 #include <fstream>
      3 #include <iostream>
      4  
      5 #include <cstdlib>
      6 #include <cstring>
      7 #include <algorithm>
      8 #include <cmath>
      9  
     10 #include <queue>
     11 #include <vector>
     12 #include <map>
     13 #include <set>
     14 #include <stack>
     15 #include <list>
     16  
     17 typedef unsigned int uint;
     18 typedef long long int ll;
     19 typedef unsigned long long int ull;
     20 typedef double db;
     21  
     22 using namespace std;
     23  
     24 inline int getint()
     25 {
     26     int res=0;
     27     char c=getchar();
     28     bool mi=false;
     29     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     30     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     31     return mi ? -res : res;
     32 }
     33 inline ll getll()
     34 {
     35     ll res=0;
     36     char c=getchar();
     37     bool mi=false;
     38     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     39     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     40     return mi ? -res : res;
     41 }
     42  
     43 db eps=1e-20;
     44 inline bool feq(db a,db b)
     45 { return fabs(a-b)<eps; }
     46 
     47 template<typename Type>
     48 inline Type avg(const Type a,const Type b)
     49 { return a+((b-a)/2); }
     50 
     51 
     52 //==============================================================================
     53 //==============================================================================
     54 //==============================================================================
     55 //==============================================================================
     56 
     57 
     58 
     59 int xlim,ylim;
     60 int n;
     61 
     62 struct point{ int x,y; point(int x=0,int y=0):x(x),y(y){} };
     63 
     64 bool cmpx(const point&a,const point&b)
     65 { return a.x!=b.x ? a.x<b.x : a.y<b.y; }
     66 bool cmpy(const point&a,const point&b)
     67 { return a.y!=b.y ? a.y<b.y : a.x<b.x; }
     68 
     69 point a[5050];
     70 
     71 int res=0;
     72 
     73 int main()
     74 {
     75     xlim=getint();
     76     ylim=getint();
     77     //Note that top-left point is (0,0).
     78     
     79     n=getint();    
     80     for(int i=0;i<n;i++)
     81     {a[i].x=getint(); a[i].y=getint(); }
     82     
     83     //scanning line algorithm.
     84     stable_sort(a,a+n,cmpy);
     85     
     86     //left to right scanning.
     87     for(int i=0;i<n;i++)
     88     {
     89         int t=0;    //top limit
     90         int b=xlim; //bottom limit
     91         for(int j=1;j<n;j++) //point-defined right limit scan.
     92         if(t<=a[j].x && a[j].x<=b)
     93         {
     94             res=max(res,(a[j].y-a[i].y)*(b-t));
     95             if(a[j].x<a[i].x) t=a[j].x;
     96             else
     97             if(a[j].x>a[i].x) b=a[j].x;
     98             else
     99             { t=b=a[i].x; break; }
    100         }
    101          res=max(res,(ylim-a[i].y)*(b-t));
    102      }
    103      //right to left scanning.
    104      for(int i=n-1;i>=0;i--)
    105      {         
    106          int t=0;    //top limit
    107          int b=xlim; //bottom limit
    108          for(int j=i-1;j>=0;j--) //point-defined left limit scan.
    109          if(t<=a[j].x && a[j].x<=b)
    110         {
    111             res=max(res,(a[i].y-a[j].y)*(b-t));
    112             if(a[j].x<a[i].x) t=a[j].x;
    113             else
    114             if(a[j].x>a[i].x) b=a[j].x;
    115             else
    116             { t=b=a[i].x; break; }
    117         }
    118          res=max(res,a[i].y*(b-t));
    119      }
    120     
    121     //top-bottom scannin;
    122     if(n>=1)
    123     {
    124         stable_sort(a,a+n,cmpx);
    125         res=max(res,a[0].x*ylim); //first
    126         res=max(res,(xlim-a[n-1].x)*ylim); //last
    127         for(int i=1;i<n;i++) //between them
    128         res=max(res,(a[i].x-a[i-1].x)*ylim);
    129     }
    130     else res=max(res,xlim*ylim);
    131     
    132     printf("%d
    ",res);
    133     
    134     return 0;
    135 }
    View Code

    扫描线.

    扫描的目的是"枚举所有的极大子矩形".详见 IOI2003 王知昆的论文.....

    我们枚举确定某些极大子矩形左端界的点,然后从左到右维护这个极大子矩形的上下界.

    注意维护的时候要保证所得到的上下界形成的矩形确实是以枚举的点作左端界点.

    并且对于每个点,要对题目给出的边界进行特判.

    并且还要反方向扫一遍.

    并且还要在与扫描线垂直的方向,把所有左/右边界由题目给出边界确定的极大子矩形枚举一遍.

    可以证明这样做以后所有的极大子矩形都被枚举掉了....

     

     

     

     

    AC VIJOS 1351 棋盘制作

      1 #include <cstdio>
      2 #include <fstream>
      3 #include <iostream>
      4  
      5 #include <cstdlib>
      6 #include <cstring>
      7 #include <algorithm>
      8 #include <cmath>
      9  
     10 #include <queue>
     11 #include <vector>
     12 #include <map>
     13 #include <set>
     14 #include <stack>
     15 #include <list>
     16  
     17 typedef unsigned int uint;
     18 typedef long long int ll;
     19 typedef unsigned long long int ull;
     20 typedef double db;
     21  
     22 using namespace std;
     23  
     24 inline int getint()
     25 {
     26     int res=0;
     27     char c=getchar();
     28     bool mi=false;
     29     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     30     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     31     return mi ? -res : res;
     32 }
     33 inline ll getll()
     34 {
     35     ll res=0;
     36     char c=getchar();
     37     bool mi=false;
     38     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     39     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     40     return mi ? -res : res;
     41 }
     42  
     43 db eps=1e-20;
     44 inline bool feq(db a,db b)
     45 { return fabs(a-b)<eps; }
     46 
     47 template<typename Type>
     48 inline Type avg(const Type a,const Type b)
     49 { return a+((b-a)/2); }
     50 
     51 
     52 //==============================================================================
     53 //==============================================================================
     54 //==============================================================================
     55 //==============================================================================
     56 
     57 
     58 int n,m;
     59 
     60 int M[2050][2050];
     61 
     62 int lmx[2050][2050];
     63 int rmx[2050][2050];
     64 
     65 int tmx[2050][2050];
     66 
     67 int res1=0,res2=0;
     68 
     69 int main()
     70 {
     71     n=getint();
     72     m=getint();
     73     
     74     for(int i=0;i<n;i++)
     75     for(int j=0;j<m;j++)
     76     M[i][j]=getint();
     77     
     78     for(int i=0;i<n;i++)
     79     {
     80         lmx[i][0]=0;
     81         for(int j=1;j<m;j++)
     82         lmx[i][j]=( M[i][j]!=M[i][j-1] ? lmx[i][j-1]+1 : 0 );
     83         
     84         rmx[i][m-1]=0;
     85         for(int j=m-2;j>=0;j--)
     86         rmx[i][j]=( M[i][j]!=M[i][j+1] ? rmx[i][j+1]+1 : 0 );
     87     }
     88     
     89     for(int j=0;j<m;j++)
     90     {
     91         tmx[0][j]=0;
     92         for(int i=1;i<n;i++)
     93         tmx[i][j]=( M[i][j]!=M[i-1][j] ? tmx[i-1][j]+1 : 0 );
     94     }
     95     
     96     for(int j=0;j<m;j++)
     97     {
     98         int l=lmx[0][j];
     99         int r=rmx[0][j];
    100         
    101         for(int i=0;i<n;i++)
    102         {
    103             res1=max(res1,(l+r+1)*(tmx[i][j]+1));
    104             int line=min(l+r+1,tmx[i][j]+1);
    105             res2=max(res2,line*line);
    106             if(i!=n-1 && tmx[i+1][j]!=0)
    107             {
    108                 l=min(l,lmx[i+1][j]);
    109                 r=min(r,rmx[i+1][j]);
    110             }
    111             else
    112             if(i!=n-1)
    113             {
    114                 l=lmx[i+1][j];
    115                 r=rmx[i+1][j];
    116             }
    117         }
    118     }
    119 
    120     printf("%d
    %d
    ",res2,res1);
    121     
    122     return 0;
    123 }
    View Code

    悬线法.

    枚举每条悬线,找到可以拓展的左右端界然后计算答案更新答案.

    左右的可扩展范围可以预处理+递推出来.

    预处理出所有点往左往右的可扩展范围.递推的时候根据点的信息,从上到下维护整条悬线的可扩展范围.

    悬线的好处就在于,预处理的时候就按照行列把每个点处理成"障碍点"或"非障碍点". 扫描线如果不做预处理,细节上会神坑(大神轻拍).

    可以证明所有的极大子矩形都能够由一条悬线扩展而来.

    这样我们就根据上面的方法枚举了所有的极大子矩形.

    写的时候注意我们枚举的是悬线,因此一但扫到了障碍点要及时将左右端界扩展到最大的可行界.

    剩下的就是细节问题.......下标略感混乱.......

     

     

     

    AC USACO 2015 Jan. Gold T1 Cow Rectangles

      1 #include <cstdio>
      2 #include <fstream>
      3 #include <iostream>
      4  
      5 #include <cstdlib>
      6 #include <cstring>
      7 #include <algorithm>
      8 #include <cmath>
      9  
     10 #include <queue>
     11 #include <vector>
     12 #include <map>
     13 #include <set>
     14 #include <stack>
     15 #include <list>
     16  
     17 typedef unsigned int uint;
     18 typedef long long int ll;
     19 typedef unsigned long long int ull;
     20 typedef double db;
     21  
     22 using namespace std;
     23  
     24 inline int getint()
     25 {
     26     int res=0;
     27     char c=getchar();
     28     bool mi=false;
     29     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     30     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     31     return mi ? -res : res;
     32 }
     33 inline ll getll()
     34 {
     35     ll res=0;
     36     char c=getchar();
     37     bool mi=false;
     38     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     39     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     40     return mi ? -res : res;
     41 }
     42  
     43 db eps=1e-20;
     44 inline bool feq(db a,db b)
     45 { return fabs(a-b)<eps; }
     46 
     47 template<typename Type>
     48 inline Type avg(const Type a,const Type b)
     49 { return a+((b-a)/2); }
     50 
     51 
     52 //==============================================================================
     53 //==============================================================================
     54 //==============================================================================
     55 //==============================================================================
     56 
     57 
     58 int n;
     59 
     60 int vx[505],xlim;
     61 int vy[505],ylim;
     62 struct point
     63 {
     64     int x,y; char type;
     65     point(int x=-1,int y=-1,char t=' '):x(x),y(y),type(t){}
     66 };
     67 
     68 point a[505];
     69 
     70 bool cmpx(const point&a,const point&b)
     71 { return a.x==b.x ? a.y<b.y : a.x<b.x; }
     72 
     73 int res=0;
     74 int resS=-1;
     75 inline void update(int cnt,int S)
     76 {
     77     if(cnt>=res)
     78     {
     79         if(cnt>res) res=cnt,resS=S;
     80         else resS=min(resS,S);
     81     }
     82 }
     83 
     84 point x[505];
     85 bool able[505];
     86 
     87 int main()
     88 {
     89     freopen("cowrect.in","r",stdin);
     90     freopen("cowrect.out","w",stdout);
     91     
     92     n=getint();
     93     
     94     for(int i=0;i<n;i++)
     95     {
     96         vx[i]=a[i].x=getint();
     97         vy[i]=a[i].y=getint();
     98         char c=getchar();
     99         while(c!='H' && c!='G') c=getchar();
    100         a[i].type=c;
    101     }
    102     
    103     stable_sort(vx,vx+n);
    104     stable_sort(vy,vy+n);
    105     xlim=(int)(unique(vx,vx+n)-vx);
    106     ylim=(int)(unique(vy,vy+n)-vy);
    107     
    108     stable_sort(a,a+n,cmpx);
    109     
    110     for(int d1=0;d1<ylim;d1++)
    111     for(int d2=d1;d2<ylim;d2++)
    112     {
    113         int l=vy[d1];
    114         int r=vy[d2];
    115         
    116         int t=0;
    117         
    118         for(int i=0;i<n;i++)
    119         if(l<=a[i].y && a[i].y<=r) x[t++]=a[i];
    120         x[t++]=point(10000,10000,'G');
    121         
    122         for(int i=0;i<t;i++) able[i]=true;
    123         
    124         for(int i=0;i<t;i++)
    125         if(x[i].type=='G' || (i!=0 && x[i-1].x==x[i].x && x[i-1].type=='G'))
    126         able[i]=false;
    127         for(int i=t-1;i>=0;i--)
    128         if(x[i].type=='G' || (i!=t-1 && x[i+1].x==x[i].x && x[i+1].type=='G'))
    129         able[i]=false;
    130         
    131         int last=0;
    132         while(!able[last] && last<t) last++;
    133         if(last!=t)
    134         {
    135             for(int i=last;i<t;i++)
    136             {
    137                 if(!able[i])
    138                 {
    139                     update(i-last,(x[i-1].x-x[last].x)*(r-l));
    140                     last=i+1;
    141                 }
    142             }
    143         }
    144     }
    145     
    146     printf("%d
    %d
    ",res,resS);
    147     
    148     return 0;
    149 }
    View Code

    叫你找出一个覆盖最多"H"点的最小矩形,并且那个矩形不含"G"点.

    $O(n^3)$ 算法......扫描线.......

    结果在"如何统计点数最多的可行区间"那里卡了好久...

    程序里先把点给拿出来...然后在最后放上一个虚节点....然后打上able标记....两个方向都要扫一遍.......

    然后预处理好左端界......然后扫一遍作统计获取答案........

    是不是很蠢......TAT

     

  • 相关阅读:
    小白学 Python 数据分析(21):pyecharts 好玩的图表(系列终篇)
    小白学 Python 数据分析(20):pyecharts 概述
    小白学 Python 数据分析(19):Matplotlib(四)常用图表(下)
    小白学 Python 数据分析(18):Matplotlib(三)常用图表(上)
    在 ASP.NET Core 程序启动前运行你的代码
    在 ASP.NET Core 项目中使用 MediatR 实现中介者模式
    在 ASP.NET Core 项目中使用 AutoMapper 进行实体映射
    [Vue 牛刀小试]:第十七章
    或许是你应该了解的一些 ASP.NET Core Web API 使用小技巧
    [Vue 牛刀小试]:第十六章
  • 原文地址:https://www.cnblogs.com/DragoonKiller/p/4420574.html
Copyright © 2020-2023  润新知