POJ 1116 Library

来源:互联网 发布:学java好的学校 编辑:程序博客网 时间:2024/06/08 08:51

终于TMD过了...细节真多,没有考虑全,看了人家的AC代码才修改成功.....唉...两次枚举+一个评估函数...评估函数除了分类讨论,还是TMD分类讨论....

#include<cstdio>#include<cmath>#include<algorithm>using namespace std;typedef struct Shelf{int y;int x;int len;int x1,x2;}Shelf;typedef struct Ans{int x,y;};Shelf s[101];int Xn,Yn,Xt,Yt,n;bool cmp(Shelf a,Shelf b){    return a.y>b.y;}Ans Judge(int c,int x)//第c个木板 离壁龛左侧有x距离  {  Ans ans={0,0};bool flag;  int left=x,right=x+Xt;//书在x上的左右端点  int pos_1,pos_2,t;  for(int i=0;i<c;i++)  {        pos_1=s[i].x+s[i].x1;      pos_2=s[i].x+s[i].x2;      if(s[i].x>=right||s[i].x+s[i].len<=left||s[i].y>=s[c].y+Yt) continue;      if(pos_2<=left)       {          if(left-pos_1<pos_1)  t=2*(left-pos_1);else t=x;          if(t<s[i].len)  ans.y+=s[i].len-t;      }           else if(pos_1>=right)      {          if(pos_2-right<Xn-pos_2) t=2*(pos_2-right);else t=Xn-right;          if(t<s[i].len)  ans.y+=s[i].len-t;      }      //以上不移动木栓        else if(pos_1<=left&&pos_2>left&&pos_2<right)      {          if(s[i].len>left) ans.y+=s[i].len-left;          ans.x++;          if(left==0) ans.x++;      }      else if(pos_1>left&&pos_1<right&&pos_2>=right)      {          if(s[i].len>Xn-right) ans.y+=s[i].len+right-Xn;          ans.x++;          if(right==Xn) ans.x++;      }      else if(pos_1<=left&&pos_2>=right)      {          int t=min(s[i].len-Xn+right,s[i].len-left);          ans.y+=t<0?0:t;          ans.x++;          if(t==s[i].len) ans.x++;      }      //以上移动一个木栓      else       {ans.x+=2;       ans.y+=s[i].len;      }  }  return ans;}Ans EnumPosition(int c)//第2次枚举{    Ans ans={1<<21,1<<21},t;    if(s[c].len<Xt||Yn-Yt<s[c].y) return ans;    for(int i=0;i+Xt<=Xn;i++)    {          t=Judge(c,i);        if(i+s[c].len<s[c].x1) continue;        if(s[c].x2+s[c].len<i+Xt) break;        if(2*(s[c].x1+s[c].x-i)>s[c].len||2*(i+Xt-s[c].x2-s[c].x)>s[c].len            ||s[c].x2+s[c].x-i>s[c].len||i+Xt-s[c].x1-s[c].x1>s[c].len) t.x++;        if(t.x<ans.x) {ans=t;continue;}        if(t.x==ans.x&&t.y<ans.y) ans=t;   }return ans;}int main(){      Ans ans,t;   while(~ scanf("%d%d%d%d%d",&Xn,&Yn,&Xt,&Yt,&n))   {      ans.x=ans.y=1<<20;    for(int i=0;i<n;i++)        scanf("%d%d%d%d%d",&s[i].y,&s[i].x,&s[i].len,&s[i].x1,&s[i].x2);    sort(s,s+n,cmp);    for(int i=0;i<n;i++)//第一次枚举    {        t=EnumPosition(i);        if(t.x<ans.x) {ans=t;continue;}        if(t.x==ans.x&&t.y<ans.y) ans=t;    }    printf("%d %d\n",ans.x,ans.y);   }}