zoukankan      html  css  js  c++  java
  • 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 }
    没有人能阻止我前进的步伐,除了我自己!
  • 相关阅读:
    Django框架基础之序列化
    资产采集
    CMDB
    数据库--三层架构
    Django 项目一补充
    评论楼
    图片预览
    验证码
    如何使用C/C++动态库与静态库中的宏
    Matlab 直线方程、采样函数
  • 原文地址:https://www.cnblogs.com/proverbs/p/2935877.html
Copyright © 2011-2022 走看看