「不会」半平面交

    一条直线把平面切成2个半平面

    一堆半平面相交的区域为半平面交

    多边形所有边的半平面交为多边形的核,

    从这一区域向所有顶点连边形成的线段全部位于多边形内。

    凸多边形的核是它自己

    

    以上废话好像都没啥用,了解就行了

    主要是怎么求

    
 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 inline int read(){
 8     int x=0;bool f=0;char ch=getchar();
 9     for(;!isdigit(ch);ch=getchar()) f=(ch=='-');
10     for(; isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
11     return f?-x:x;
12 }
13 const int maxn=1e3+7;
14 const double eps=1e-8;
15 inline int dcmp(double a){
16     if(fabs(a)<eps) return 0; return a<0?-1:1;
17 }
18 
19 #define vec dot
20 struct dot{
21     double x,y; dot(){}
22     dot(double u,double v):x(u),y(v){}
23     dot friend operator + (dot a,dot b){return dot(a.x+b.x,a.y+b.y);}
24     dot friend operator - (dot a,dot b){return dot(a.x-b.x,a.y-b.y);}
25     dot friend operator * (dot a,double b){return dot(a.x*b,a.y*b);}
26     dot friend operator / (dot a,double b){return dot(a.x/b,a.y/b);}
27     double friend operator ^ (dot a,dot b){return a.x*b.y-a.y*b.x;}//叉乘
28 }a[maxn];
29 struct line{
30     dot s,t; vec v; double ang; line(){}
31     line(dot a,dot b){s=a;t=b;v=b-a;ang=atan2(t.y-s.y,t.x-s.x);}//先传y后传x
32     inline bool friend operator < (line a,line b){
33         if(dcmp(a.ang-b.ang)) return a.ang<b.ang;
34         return (a.v^(b.s-a.s))<0;
35     }
36 }l[maxn];
37 inline bool left(line a,dot b){return (a.v^(b-a.s))>0;}
38 dot meet(line a,line b){//定比分点公式
39     dot A=a.s,B=a.t,C=b.s,D=b.t;
40     double s1=(B-A)^(C-A),s2=(D-A)^(B-A);
41     return (D*s1+C*s2)/(s1+s2);
42 }
43 
44 line q[maxn];
45 dot p[maxn];
46 int L,R,cnt;
47 double ans;
48 
49 int n,m;
50 int main(){
51     n=read();
52     for(int i=1;i<=n;++i){
53         m=read();
54         dot tmp,las,st;
55         for(int j=1;j<=m;++j){
56             scanf("%lf%lf",&tmp.x,&tmp.y);
57             if(j^1) l[++cnt]=line(las,tmp);
58             else st=tmp; las=tmp;
59         }
60         l[++cnt]=line(las,st);
61     }
62     sort(l+1,l+cnt+1);
63     n=1;
64     for(int i=2;i<=cnt;++i) if(dcmp(l[i].ang-l[i-1].ang)) l[++n]=l[i];
65     L=1;R=0; q[++R]=l[1];
66     for(int i=2;i<=n;++i){
67         while(L<R&&!left(l[i],p[R-1])) --R;
68         while(L<R&&!left(l[i],p[L])) ++L;
69         q[++R]=l[i];
70         if(L<R) p[R-1]=meet(q[R],q[R-1]);
71     }
72     while(L<R&&!left(q[L],p[R-1])) --R;
73     if(L<R) p[R]=meet(q[L],q[R]);
74     if(R-L+1>=3){
75         for(int i=L;i<R;++i) ans+=p[i]^p[i+1];
76         ans+=p[R]^p[L]; ans/=2;
77     }
78     printf("%.3lf\n",ans);
79     return 0;
80 }
抄的*miracle*的模板

    然后人被几道简单题切没了

 

    「赛车」 凸包

    「Fe人双项比赛」 三分,魔改二分会死人,

      另外需要注意的一点是$log_21e19$和$log_21e15$有着天壤之别,后者直接T飞

    「瞭望塔」

      用skyh的话说,一次函数减一次函数得一次函数

      所以答案出在拐点,平面交求出来暴枚就可以

    「射箭」

      化化柿子就变成了二分答案+半平面交+卡精好题

    「Saber VS Lancer」

      对于三种路程比例相同的所有情况,结果都是一样的

      于是三个变量变成两个比值,不等号要变。

    「小凸想跑步」

      如果会点到直线距离公式好像不难

    「escape」

      垂直评分线找控制区域,接壤的连边,多源最短路

    「wps岛」

      用miku的话说,把图画出来就行了

      画出来后发现一些边没用了,因为显然有更好的代替他们(三角形两边之和大于第三边

      再观察发现有用的就是某点编号最大和最小的未被删除的边

      只考虑他们,半平面交,周长

      

posted @ 2020-01-10 06:37  Yxsplayxs  阅读(188)  评论(0编辑  收藏  举报