一条直线把平面切成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 ",ans); 79 return 0; 80 }
然后人被几道简单题切没了
「赛车」 凸包
「Fe人双项比赛」 三分,魔改二分会死人,
另外需要注意的一点是$log_21e19$和$log_21e15$有着天壤之别,后者直接T飞
「瞭望塔」
用skyh的话说,一次函数减一次函数得一次函数
所以答案出在拐点,平面交求出来暴枚就可以
「射箭」
化化柿子就变成了二分答案+半平面交+卡精好题
「Saber VS Lancer」
对于三种路程比例相同的所有情况,结果都是一样的
于是三个变量变成两个比值,不等号要变。
「小凸想跑步」
如果会点到直线距离公式好像不难
「escape」
垂直评分线找控制区域,接壤的连边,多源最短路
「wps岛」
用miku的话说,把图画出来就行了
画出来后发现一些边没用了,因为显然有更好的代替他们(三角形两边之和大于第三边
再观察发现有用的就是某点编号最大和最小的未被删除的边
只考虑他们,半平面交,周长