• 【模板】半平面交


    写半平面交的时候注意以下几点
    1.考虑x,y是否有正负号限制。
    2.注意特判分母为0的情况。
    3.对于分母正负不确定的情况分类讨论。

    #include<iostream>
    #include<cctype>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<ctime>
    #include<cstdlib>
    #include<algorithm>
    #define N 1100000
    #define L 1000000
    #define eps 1e-7
    #define inf 1e9+7
    #define db double
    #define ll long long
    #define ldb long double
    using namespace std;
    inline int read()
    {
        char ch=0;
        int x=0,flag=1;
        while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
        while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*flag;
    }
    const db phi=acos(-1);
    int dcmp(db x)
    {
    	if(fabs(x)<=eps)return 0;
    	else return x>0?+1:-1;
    }
    struct vec
    {
        db x,y;
        vec(db xx=0,db yy=0){x=xx,y=yy;}
        db ang(){return atan2(y,x);}
        db len(){return sqrt(x*x+y*y);}
    	vec operator+(vec a){return (vec){x+a.x,y+a.y};}
        vec operator-(vec a){return (vec){x-a.x,y-a.y};}
        vec operator*(db k){return (vec){x*k,y*k};}
        vec operator/(db k){return (vec){x/k,y/k};}
        bool operator==(vec a){return !dcmp(x-a.x)&&!dcmp(y-a.y);}
    }p[N];
    typedef vec pot;
    db dot(vec a,vec b){return a.x*b.x+a.y*b.y;}
    db cross(vec a,vec b){return a.x*b.y-a.y*b.x;}
    struct line
    {
    	pot s,t;db ang;
    	line(pot ss=vec(),pot tt=vec()){s=ss;t=tt;ang=(tt-ss).ang();}
    }f[N];
    bool cmp(line a,line b)
    {
    	int k=dcmp(a.ang-b.ang);
    	if(k)return k<0;
    	else return dcmp(cross(a.t-a.s,b.t-a.s))<0; 
    }
    bool pal(line a,line b)
    {
    	return !dcmp(cross(a.t-a.s,b.t-b.s));
    }
    pot get(line a,line b)
    {
    	return a.s+(a.t-a.s)*(cross(b.t-b.s,a.s-b.s)/cross(a.t-a.s,b.t-b.s));
    }
    bool onright(pot a,line l)
    {
    	return dcmp(cross(a-l.s,l.t-l.s))>0;
    }
    pot Q[N];
    line q[N];
    db solve(int cnt)
    {
    	int l=1,r=1;q[1]=f[1];
    	for(int i=2;i<=cnt;i++)
    	if(dcmp(f[i].ang-f[i-1].ang))
    	{
    		if(l<r&&(pal(q[l],q[l+1])||pal(q[r],q[r-1])))return 0;
    		while(l<r&&onright(Q[r-1],f[i]))r--;
    		while(l<r&&onright(Q[l],f[i]))l++;
    		q[++r]=f[i];Q[r-1]=get(q[r-1],q[r]);
    	}	
    	while(l<r&&onright(Q[r-1],q[l]))r--;
    	while(l<r&&onright(Q[l],q[r]))l++;
    	if(r-l<=1)return 0;
    	Q[r]=get(q[l],q[r]);
    	db ans=0;
    	for(int i=l;i<=r;i++)
    	{
    		if(i!=r)ans+=cross(Q[i],Q[i+1]);
    		else ans+=cross(Q[r],Q[l]);
    	}
    	return fabs(ans)/2.0;
    }
    int main()
    {
    	int n=read(),cnt=0;
    	for(int o=1;o<=n;o++)
    	{
    		int m=read();
    		for(int i=1;i<=m;i++)
    		{
    			p[i].x=read();p[i].y=read();
    			if(i!=1)f[++cnt]=(line){p[i-1],p[i]};
    			if(i==m)f[++cnt]=(line){p[i],p[1]};
    		}	
    	}
    	f[++cnt]=(line){(pot){-inf,-inf},(pot){+inf,-inf}};
    	f[++cnt]=(line){(pot){+inf,-inf},(pot){+inf,+inf}};
    	f[++cnt]=(line){(pot){+inf,+inf},(pot){-inf,+inf}};
    	f[++cnt]=(line){(pot){-inf,+inf},(pot){-inf,-inf}};
    	sort(f+1,f+cnt+1,cmp);
    	printf("%.3lf",solve(cnt));
    	return 0;
    }
    
  • 相关阅读:
    第四周作业
    第三周作业
    第二周作业
    互联网公司采用增量模型做开发的优势
    面向过程分析方法与面向对象分析方法到底区别
    项目测试中的黑盒测试和白盒测试
    立项说明书里面的项目概述。
    项目开发中的一些问题
    面向对象之我见
    [自翻]fasthttp中文文档(持续更新)
  • 原文地址:https://www.cnblogs.com/Creed-qwq/p/10169605.html
Copyright © 2020-2023  润新知