POJ 1274 半平面交

题意:

一块有n个点的凸多边形面包要沾牛奶,每次可以沾的深度是h, 总共可以沾 k 次, 求最大沾取牛奶的面积。

 

题解:

枚举k条边,然后半平面交找最小剩余面积。。

又查不出错了,不想对拍了,这几天写计算几何都恶心死了,各种数据弱,模板写错了都不知道,下次用被卡的时候死活检查不出来了。。

改了好几回模板了,现在应该是对的,不知道我那里没考虑到,wa啊。。。

 

 

View Code
  1 #include <iostream>

  2 #include <cstring>

  3 #include <cstdlib>

  4 #include <cstdio>

  5 #include <algorithm>

  6 #include <cmath>

  7 

  8 #define N 222

  9 #define EPS 1e-7

 10 #define PI 3.14159265358979323

 11 #define INF 1e10

 12 

 13 using namespace std;

 14 

 15 struct PO

 16 {

 17     double x,y;

 18     void in(double x1,double y1)

 19     {

 20         x=x1,y=y1;

 21     }

 22     void prt() {printf("%lf     %lf\n",x,y);}

 23 }p[N],tp[N],f[N],s[N],o;

 24 

 25 struct LI

 26 {

 27     PO a,b;

 28     void prt() {printf("%lf    %lf    %lf     %lf\n",a.x,a.y,b.x,b.y);}

 29 }li[N],sl[N];

 30 

 31 int n,k,num;

 32 bool fg[N];

 33 double smin=INF,h;

 34 

 35 inline PO operator -(PO a,PO b)

 36 {

 37     PO c;

 38     c.x=a.x-b.x; c.y=a.y-b.y;

 39     return c;

 40 }

 41 

 42 inline int dc(double x)

 43 {

 44     if(x>EPS) return 1;

 45     else if(x<-EPS) return -1;

 46     return 0;

 47 }

 48 

 49 inline double cross(PO &a,PO &b,PO &c)

 50 {

 51     return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);

 52 }

 53 

 54 inline double getlen(PO &a)

 55 {

 56     return sqrt(a.x*a.x+a.y*a.y);

 57 }

 58 

 59 inline PO rotate(PO a,double sss,double ccc)

 60 {

 61     PO ans;

 62     ans.x=a.x*ccc-a.y*sss;

 63     ans.y=a.x*sss+a.y*ccc;

 64     return ans;

 65 }

 66 

 67 inline PO getf(PO &a,PO &b)

 68 {

 69     PO ans; ans=b-a;

 70     ans=rotate(ans,sin(0.5*PI),cos(0.5*PI));

 71     double kk=getlen(ans);

 72     ans.x/=kk; ans.y/=kk;

 73     return ans;

 74 }

 75 

 76 inline PO getpoint(PO &a,PO &b,PO &c,PO &d)

 77 {

 78     PO ans,tp=b-a;

 79     double k1=cross(a,d,c);

 80     double k2=cross(b,c,d);

 81     ans.x=a.x+tp.x*k1/(k1+k2);

 82     ans.y=a.y+tp.y*k1/(k1+k2);

 83     return ans;

 84 }

 85 

 86 inline double getarea(PO *a,int g)

 87 {

 88     double ans=0.0;

 89     a[g+1]=a[1];

 90     for(int i=1;i<=g;i++) ans+=cross(o,a[i],a[i+1]);

 91     return ans;

 92 }

 93 

 94 inline void change(PO *a,int g)

 95 {

 96     for(int i=1;i<=(g>>1);g++) swap(a[i],a[g-i+1]);

 97 }

 98 

 99 inline void read()

100 {

101     memset(fg,0,sizeof fg);

102     for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);

103     if(dc(getarea(p,n))<=0) change(p,n);

104     for(int i=1;i<n;i++)

105     {

106         li[i].a=p[i];

107         li[i].b=p[i+1];

108     }

109     li[n].a=p[n]; li[n].b=p[1];

110     for(int i=1;i<=n;i++) f[i]=getf(li[i].a,li[i].b);

111 }

112 

113 inline void getcut()

114 {

115     tp[1].in(-INF,-INF); tp[2].in(INF,-INF);

116     tp[3].in(INF,INF); tp[4].in(-INF,INF); tp[5]=tp[1];

117     int cp=4,tc;

118     for(int i=1;i<=n;i++)

119     {

120         tc=0;

121         for(int j=1;j<=cp;j++)

122         {

123             if(dc(cross(sl[i].a,sl[i].b,tp[j]))>=0) s[++tc]=tp[j];

124             if(dc(cross(sl[i].a,sl[i].b,tp[j])*cross(sl[i].a,sl[i].b,tp[j+1]))<0)

125                 s[++tc]=getpoint(sl[i].a,sl[i].b,tp[j],tp[j+1]);

126         }

127         s[tc+1]=s[1];

128         for(int j=1;j<=tc+1;j++) tp[j]=s[j];

129         cp=tc;

130     }

131     num=cp;

132 }

133 

134 inline void calc()

135 {

136     for(int i=1;i<=n;i++)

137     {

138         sl[i]=li[i];

139         if(!fg[i]) continue;

140         sl[i].a.x=sl[i].a.x+h*f[i].x;

141         sl[i].a.y=sl[i].a.y+h*f[i].y;

142         sl[i].b.x=sl[i].b.x+h*f[i].x;

143         sl[i].b.y=sl[i].b.y+h*f[i].y;

144     }

145     getcut();

146     if(!num) smin=0.0;

147     else smin=min(smin,fabs(getarea(s,num))*0.5);

148     //printf("%lf\n",smin);for(int i=1;i<=num;i++) s[i].prt();puts("\n");

149 }

150 

151 inline void dfs(int x,int nu)

152 {

153     if(dc(smin)==0) return;

154     if(n-x+1<k-nu) return;

155     if(nu==k) {calc();return;}

156     if(x>n) return;

157     fg[x]=1; dfs(x+1,nu+1);

158     fg[x]=0; dfs(x+1,nu);

159 }

160 

161 inline void go()

162 {

163     double sum=fabs(getarea(p,n))*0.5;

164     dfs(1,0);

165     //cout<<sum<<endl<<smin<<endl;

166     printf("%.2lf\n",sum-smin);

167 }

168 

169 int main()

170 {

171     while(scanf("%d%d%lf",&n,&k,&h))

172     {

173         if(n==0&&k==0&&dc(h)==0) break;

174         k=min(k,n);

175         if(dc(h)==0||k==0) puts("0.00");

176         else read(),go();

177     }

178     return 0;

179 }

 

 

你可能感兴趣的:(poj)