POJ 1271&& uva 10117 Nice Milk

来源:互联网 发布:零境网络漫画 编辑:程序博客网 时间:2024/06/06 17:54

题意:给你一个凸多边形的面包,然后告诉你牛奶的高度,和可以进行最多k次蘸牛奶,求面包最多能蘸到牛奶的面积

思路:dfs枚举边,然后向内推进h,用半平面交求不能蘸到牛奶的面积,用总面积减去面积,维护最大值

有一个小trick:k有可能会比边大,需要判断一下;

不得不说不知道是uva的机器比poj好还是数据比poj少,uva上只跑了300ms,而poj接近600ms。。。。。

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<algorithm>#define inf 0x7ffffffusing namespace std;const double eps=1e-8;int n,k,h,top,bot,dq[1000000];int ln;double ans,area,marea;struct P{double x,y;P(){}P(double x,double y):x(x),y(y){}P operator +(P p){return P(x+p.x,y+p.y);}P operator -(P p){return P(x-p.x,y-p.y);}P operator *(double d){return P(x*d,y*d);}double det(P p){return x*p.y-y*p.x;}};P p[1000000],s[1000000];struct Line{P a,b;double angle;};Line l[1000000],l1[1000000],l2[1000000];int dblcmp(double k){if(fabs(k)<eps)return 0;return k>0?1:-1;}P in(Line a,Line b){  return a.a+(a.b-a.a)*((b.b-b.a).det(b.a-a.a)/(b.b-b.a).det(a.b-a.a));  }  bool judge(Line a,Line b,Line c){  P r=in(b,c);  return dblcmp((a.a-r).det(a.b-r))<0;  //顺时针大于0,逆时针小于0;  }bool cmp(Line a,Line b){  int d=dblcmp(a.angle-b.angle);  if(!d)  return dblcmp((b.a-a.a).det(b.b-a.a))>0;  return d<0;  }double dis(P a,P b){double c=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);return sqrt(c);}void getarea(){area=0;for(int i=0;i<n;i++)area+=(p[i].x*p[i+1].y-p[i].y*p[i+1].x);area=fabs(area);area/=2;}Line getmove(double r,Line l){Line l1;double x=l.a.x-l.b.x;//顺逆时针只需要交换a,b就可以了。。。顺时针b-a,逆时针a-b  double y=l.a.y-l.b.y;  double L=dis(l.a,l.b);  l1.a.x=(l.a.x+r*y/L);  l1.a.y=(l.a.y-r*x/L);  l1.b.x=(l.b.x+r*y/L);  l1.b.y=(l.b.y-r*x/L);  l1.angle=l.angle; return l1;}void solve(){int i,j;for(i=0,j=0;i<ln;i++)  {  l2[i]=l1[i];if(dblcmp(l2[i].angle-l2[j].angle)>0)  l2[++j]=l2[i];  }  int len=j+1;  top=1;  bot=0;  dq[0]=0;  dq[1]=1;  for(i=2;i<len;i++)  {  while(top>bot && judge(l2[i],l2[dq[top]],l2[dq[top-1]])) top--;  while(top>bot && judge(l2[i],l2[dq[bot]],l2[dq[bot+1]])) bot++;  dq[++top]=i;  }  while(top>bot && judge(l2[dq[bot]],l2[dq[top]],l2[dq[top-1]])) top--;  while(top>bot && judge(l2[dq[top]],l2[dq[bot]],l2[dq[bot+1]])) bot++;dq[++top]=dq[bot];int pn=0;for(pn=0,i=bot;i<top;i++,pn++)  {  s[pn]=in(l2[dq[i+1]],l2[dq[i]]);  }s[pn]=s[0];if(pn>=3){marea=0;  for(int i=0;i<pn;i++)  {  marea+=(s[i].x*s[i+1].y-s[i].y*s[i+1].x);  }  marea=fabs(marea);  marea/=2.0;ans=max(ans,area-marea);}else{ans=max(ans,area);}}int vis[100000];int kep[1000];void dfs(int index,int num,double r){if(num-k+index>ln)return;if(num==k){solve();return ;}for(int i=index;i<ln;i++){if(!vis[i]){vis[i]=1;l1[i]=getmove(r,l[i]);dfs(i+1,num+1,r);vis[i]=0;l1[i]=l[i];}}}int main(){while(~scanf("%d%d%d",&n,&k,&h) && !(n==k && k==h && h==0)){memset(vis,0,sizeof(vis));ln=0;ans=0;for(int i=0;i<n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);p[n]=p[0];for(int i=0;i<n;i++){l[ln].a=p[i];l[ln].b=p[i+1];l[ln].angle=atan2(l[ln].a.y-l[ln].b.y,l[ln].b.x-l[ln].a.x);l1[ln]=l[ln];ln++;}if(k>ln)k=ln;sort(l,l+ln,cmp);sort(l1,l1+ln,cmp);getarea();double r=(double)h;dfs(0,0,r);printf("%.2lf\n",ans);}return 0;}


0 0