zoukankan      html  css  js  c++  java
  • BZOJ4118 : [Wf2015]Window Manager

    OPEN、CLOSE、RESIZE操作直接模拟即可。

    对于MOVE,设$f_i$表示$i$号矩形的坐标,先无视边界通过DP求出每个矩形的坐标,再根据边界反向用第二次DP求出被移动矩形移动的真实距离,再正着进行一次DP即可。

    时间复杂度$O(n^3)$。

    #include<cstdio>
    #include<algorithm>
    #define N 260
    #define rep(i) for(int i=1;i<=n;i++)
    using namespace std;
    int xm,ym,n,remain,cnt,x,y,w,h,dx,dy,p,f[N],v[N];char op[9];
    struct P{
      int x,y,w,h;bool ex;
      P(){}
      P(int _x,int _y,int _w,int _h){x=_x,y=_y,w=_w,h=_h,ex=1;}
    }a[N];
    inline bool between(int a,int b,int c){return a<=c&&c<=b;}
    inline bool cross(int a,int b,int c,int d){
      if(d<a||c>b)return 0;
      return 1;
    }
    inline int getid(int x,int y){
      rep(i)if(a[i].ex&&between(a[i].x,a[i].x+a[i].w-1,x)&&between(a[i].y,a[i].y+a[i].h-1,y))return i;
      return 0;
    }
    inline int Open(int x,int y,int w,int h){
      if(x+w>xm||y+h>ym)return 0;
      rep(i)if(a[i].ex&&cross(a[i].x,a[i].x+a[i].w-1,x,x+w-1)&&cross(a[i].y,a[i].y+a[i].h-1,y,y+h-1))return 0;
      a[++n]=P(x,y,w,h);
      remain++;
      return 1;
    }
    inline void Close(int p){
      a[p].ex=0;
      remain--;
    }
    inline int Resize(int p,int w,int h){
      int x=a[p].x,y=a[p].y;
      if(x+w>xm||y+h>ym)return 0;
      rep(i)if(i!=p&&a[i].ex&&cross(a[i].x,a[i].x+a[i].w-1,x,x+w-1)&&cross(a[i].y,a[i].y+a[i].h-1,y,y+h-1))return 0;
      a[p].w=w,a[p].h=h;
      return 1;
    }
    int dfs11(int x){
      if(v[x])return f[x];
      v[x]=1;
      rep(i)if(a[i].ex&&cross(a[i].y,a[i].y+a[i].h-1,a[x].y,a[x].y+a[x].h-1)&&a[i].x<a[x].x)f[x]=max(f[x],dfs11(i)+a[i].w);
      return f[x];
    }
    int dfs12(int x){
      if(!v[x])return f[x];
      v[x]=0;
      f[x]=min(f[x],xm-a[x].w);
      rep(i)if(a[i].ex&&cross(a[i].y,a[i].y+a[i].h-1,a[x].y,a[x].y+a[x].h-1)&&a[i].x>a[x].x)f[x]=min(f[x],dfs12(i)-a[x].w);
      return f[x];
    }
    int dfs21(int x){
      if(v[x])return f[x];
      v[x]=1;
      rep(i)if(a[i].ex&&cross(a[i].y,a[i].y+a[i].h-1,a[x].y,a[x].y+a[x].h-1)&&a[i].x>a[x].x)f[x]=min(f[x],dfs21(i)-a[x].w);
      return f[x];
    }
    int dfs22(int x){
      if(!v[x])return f[x];
      v[x]=0;
      f[x]=max(f[x],0);
      rep(i)if(a[i].ex&&cross(a[i].y,a[i].y+a[i].h-1,a[x].y,a[x].y+a[x].h-1)&&a[i].x<a[x].x)f[x]=max(f[x],dfs22(i)+a[i].w);
      return f[x];
    }
    int dfs31(int x){
      if(v[x])return f[x];
      v[x]=1;
      rep(i)if(a[i].ex&&cross(a[i].x,a[i].x+a[i].w-1,a[x].x,a[x].x+a[x].w-1)&&a[i].y<a[x].y)f[x]=max(f[x],dfs31(i)+a[i].h);
      return f[x];
    }
    int dfs32(int x){
      if(!v[x])return f[x];
      v[x]=0;
      f[x]=min(f[x],ym-a[x].h);
      rep(i)if(a[i].ex&&cross(a[i].x,a[i].x+a[i].w-1,a[x].x,a[x].x+a[x].w-1)&&a[i].y>a[x].y)f[x]=min(f[x],dfs32(i)-a[x].h);
      return f[x];
    }
    int dfs41(int x){
      if(v[x])return f[x];
      v[x]=1;
      rep(i)if(a[i].ex&&cross(a[i].x,a[i].x+a[i].w-1,a[x].x,a[x].x+a[x].w-1)&&a[i].y>a[x].y)f[x]=min(f[x],dfs41(i)-a[x].h);
      return f[x];
    }
    int dfs42(int x){
      if(!v[x])return f[x];
      v[x]=0;
      f[x]=max(f[x],0);
      rep(i)if(a[i].ex&&cross(a[i].x,a[i].x+a[i].w-1,a[x].x,a[x].x+a[x].w-1)&&a[i].y<a[x].y)f[x]=max(f[x],dfs42(i)+a[i].h);
      return f[x];
    }
    inline int Move(int p,int dx,int dy){
      if(dx+dy==0)return 0;
      int x=a[p].x,y=a[p].y,t;
      if(dx>0){
        rep(i)v[i]=0,f[i]=a[i].x;
        f[p]+=dx;
        rep(i)if(a[i].ex)dfs11(i);
        t=dfs12(p);
        rep(i)v[i]=0,f[i]=a[i].x;
        f[p]=t;
        rep(i)if(a[i].ex)dfs11(i);
        rep(i)if(a[i].ex)a[i].x=f[i];
        return f[p]-x;
      }else if(dx<0){
        rep(i)v[i]=0,f[i]=a[i].x;
        f[p]+=dx;
        rep(i)if(a[i].ex)dfs21(i);
        t=dfs22(p);
        rep(i)v[i]=0,f[i]=a[i].x;
        f[p]=t;
        rep(i)if(a[i].ex)dfs21(i);
        rep(i)if(a[i].ex)a[i].x=f[i];
        return f[p]-x;
      }else if(dy>0){
        rep(i)v[i]=0,f[i]=a[i].y;
        f[p]+=dy;
        rep(i)if(a[i].ex)dfs31(i);
        t=dfs32(p);
        rep(i)v[i]=0,f[i]=a[i].y;
        f[p]=t;
        rep(i)if(a[i].ex)dfs31(i);
        rep(i)if(a[i].ex)a[i].y=f[i];
        return f[p]-y;
      }else{
        rep(i)v[i]=0,f[i]=a[i].y;
        f[p]+=dy;
        rep(i)if(a[i].ex)dfs41(i);
        t=dfs42(p);
        rep(i)v[i]=0,f[i]=a[i].y;
        f[p]=t;
        rep(i)if(a[i].ex)dfs41(i);
        rep(i)if(a[i].ex)a[i].y=f[i];
        return f[p]-y;
      }
      return 0;
    }
    inline int abs(int x){return x>0?x:-x;}
    int main(){
      scanf("%d%d",&xm,&ym);
      while(~scanf("%s%d%d",op,&x,&y)){
        cnt++;
        if(op[0]=='O'){
          scanf("%d%d",&w,&h);
          if(!Open(x,y,w,h))printf("Command %d: OPEN - window does not fit
    ",cnt);
        }
        if(op[0]=='C'){
          p=getid(x,y);
          if(!p)printf("Command %d: CLOSE - no window at given position
    ",cnt);
          else Close(p);
        }
        if(op[0]=='R'){
          scanf("%d%d",&w,&h);
          p=getid(x,y);
          if(!p)printf("Command %d: RESIZE - no window at given position
    ",cnt);
          else if(!Resize(p,w,h))printf("Command %d: RESIZE - window does not fit
    ",cnt);
        }
        if(op[0]=='M'){
          scanf("%d%d",&dx,&dy);
          p=getid(x,y);
          if(!p)printf("Command %d: MOVE - no window at given position
    ",cnt);
          else{
            p=Move(p,dx,dy);
            if(abs(p)!=abs(dx+dy))printf("Command %d: MOVE - moved %d instead of %d
    ",cnt,abs(p),abs(dx+dy));
          }
        }
      }
      printf("%d window(s):
    ",remain);
      rep(i)if(a[i].ex)printf("%d %d %d %d
    ",a[i].x,a[i].y,a[i].w,a[i].h);
      return 0;
    }
    

      

  • 相关阅读:
    750. Number Of Corner Rectangles
    [Project Euler] 3. Largest Prime factor
    [Project Euler] 2. Even Fibonacci numbers
    Jmeter学习笔记3-参数化
    SQL多表连接查询补充
    Jmeter学习笔记2-原件作用域与执行顺序
    Jmeter学习笔记1-实践介绍
    运用badboy录制jmeter脚本
    【SQL提数】左连接使用
    【功能测试技巧2】dubbo引起的数据精度的思考
  • 原文地址:https://www.cnblogs.com/clrs97/p/5651895.html
Copyright © 2011-2022 走看看