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\n",cnt);
    }
    if(op[0]=='C'){
      p=getid(x,y);
      if(!p)printf("Command %d: CLOSE - no window at given position\n",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\n",cnt);
      else if(!Resize(p,w,h))printf("Command %d: RESIZE - window does not fit\n",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\n",cnt);
      else{
        p=Move(p,dx,dy);
        if(abs(p)!=abs(dx+dy))printf("Command %d: MOVE - moved %d instead of %d\n",cnt,abs(p),abs(dx+dy));
      }
    }
  }
  printf("%d window(s):\n",remain);
  rep(i)if(a[i].ex)printf("%d %d %d %d\n",a[i].x,a[i].y,a[i].w,a[i].h);
  return 0;
}

  

posted @ 2016-07-07 23:09  Claris  阅读(332)  评论(0编辑  收藏  举报