POJ 1279 半平面交

题意:
求一任意多边形的核的面积

 

题解:

半平面交。第一次搞。。。找了半天错,又和题解一样了。

 

View Code
  1 #include <iostream>

  2 #include <algorithm>

  3 #include <cstdlib>

  4 #include <cstdio>

  5 #include <cstring>

  6 #include <cmath>

  7 

  8 #define N 2222

  9 #define EPS 1e-7

 10 #define INF 1e9

 11 

 12 using namespace std;

 13 

 14 struct PO

 15 {

 16     double x,y;

 17 }p[N],tp[N],s[N],o;

 18 

 19 int n;

 20 

 21 inline void read()

 22 {

 23     scanf("%d",&n);

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

 25     p[n+1]=p[1];

 26 }

 27 

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

 29 {

 30     PO c;

 31     c.x=a.x-b.x;

 32     c.y=a.y-b.y;

 33     return c;

 34 }

 35 

 36 inline int dc(double x)

 37 {

 38     if(x>EPS) return 1;

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

 40     return 0;

 41 }

 42 

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

 44 {

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

 46 }

 47 

 48 inline double getarea(PO *a,int n)//多边形面积,逆时针为正 

 49 {

 50     double res=0.0;

 51     for(int i=1;i<=n;i++) res+=cross(o,a[i],a[i+1]);

 52     return res*0.5;

 53 }

 54 

 55 inline PO getpoint(PO &a,PO &b,PO &c,PO &d)//直线交点 

 56 {

 57     PO ans,tp=b-a;

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

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

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

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

 62     return ans;

 63 }

 64 

 65 inline void change()//变顺时针为逆时针 

 66 {

 67     for(int i=1;i<=(n>>1);i++) swap(p[i],p[n-i+1]);

 68     p[n+1]=p[1];

 69 }

 70 

 71 void prt(PO a)

 72 {

 73     printf("%lf   %lf\n",a.x,a.y);

 74 }

 75 

 76 inline void getcut()

 77 {

 78     tp[1].x=tp[5].x=-INF,tp[1].y=tp[5].y=-INF;

 79     tp[2].x=INF,tp[2].y=-INF;

 80     tp[3].x=INF,tp[3].y=INF;

 81     tp[4].x=-INF,tp[4].y=INF;

 82     

 83     int cp=4,tc;

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

 85     {

 86         tc=0;

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

 88         {

 89             if(dc(cross(p[i],p[i+1],tp[j]))>=0) s[++tc]=tp[j];

 90             if(dc(cross(p[i],p[i+1],tp[j])*cross(p[i],p[i+1],tp[j+1]))<0)

 91                 s[++tc]=getpoint(p[i],p[i+1],tp[j],tp[j+1]);

 92         }

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

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

 95         cp=tc;

 96     }

 97     n=cp;

 98 }

 99 

100 inline void go()

101 {

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

103     getcut();

104     printf("%.2lf\n",fabs(getarea(s,n)));

105 }

106 

107 int main()

108 {

109     int cas; scanf("%d",&cas);

110     while(cas--) read(),go();

111     return 0;

112 }

 

 

你可能感兴趣的:(poj)