zoukankan      html  css  js  c++  java
  • 省选模板复习—【计算几何】

    头文件:

    const double eps=1e-8;
    const double pi=acos(-1);
    inline double P(double x){
    	return x*x;
    }
    inline int sign(double x){
    	return fabs(x)<eps?0:(x>0?1:-1);
    }
    struct point{
    	double x,y;
    	point(double _x=0,double _y=0):x(_x),y(_y){}
    	friend inline point operator +(const point &a,const point &b){
    		return point(a.x+b.x,a.y+b.y);
    	}
    	friend inline point operator -(const point &a,const	point &b){
    		return point(a.x-b.x,a.y-b.y);
    	}
    	friend inline point operator *(const point &a,const double &b){
    		return point(a.x*b,a.y*b);
    	}
    	friend inline point operator /(const point &a,const double &b){
    		return point(a.x/b,a.y/b);
    	}
    	friend inline double operator ^(const point &a,const point &b){
    		return a.x*b.x+a.y*b.y;
    	}
    	friend inline double operator *(const point &a,const point &b){
    		return a.x*b.y-a.y*b.x;
    	}
    	friend inline bool operator <(const point &a,const point &b){
    		return (a.x==b.x)?a.y<b.y:a.x<b.x;
    	}
    	inline void rotate(double t){
    		double px=x,py=y;
    		x=px*cos(t)-py*sin(t),y=px*sin(t)+py*cos(t);
    	}
    	inline double ang(){
    		return atan2(y,x);
    	}
    	inline double calc(){
    		return P(x)+P(y);
    	}
    }
    struct line{
    	point s,e;int id;
    	double rad;
    	line(){}
    	line(point x,point y){
    		s=x,e=y,rad=(y-x).ang();
    	}
    	friend inline bool operator <(const line &a,const line &b){
    		return sign(a.rad-b.rad)?sign(a.rad-b.rad)<0:sign((a.e-a.s)*(b.e-a.s))>0;
    	}
    }
    

    凸包

    (POJ3348)

    point p[N],q[N];
    int n,tot,top;
    inline bool comp(const point &a,const point &b){
    	double k=(a-p[1])*(b-p[1]);
    	return sign(k)?k>0:(a-p[1]).calc()<(b-p[1]).calc();//关于长度,短的在前
    }
    void graham(){
    	for(int i=2;i<=n;i++){
    		if(p[i]<p[1])swap(p[1],p[i]);
    	}
    	sort(p+2,p+n+1,comp);//从2、
    	q[top=1]=p[1];
    	for(int i=2;i<=n;i++){
    		while(top>=2&&sign((p[i]-q[top-1])*(q[top]-q[top-1]))>=0)top--;//相同也弹出
    		q[++top]=p[i];
    	}
    	q[top+1]=q[1];
    }
    inline int area(){
    	int res=0;
    	for(int i=1;i<=top;i++)res+=q[i]*q[i+1];
    	return res/100;
    }
    int main(){
    	n=read();
    	for(int i=1;i<=n;i++)p[i].x=read(),p[i].y=read();
    	graham();
    	cout<<area();
    }
    

    旋转卡壳

    (POJ2187)

    inline int nxt(int x){
    	return x==m?1:x+1;
    }
    inline double area(const point &a,const point &b,const point &c){
    	return (b-a)*(c-a);
    }
    int main(){
    	n=read();
    	for(int i=1;i<=n;i++)p[i].x=read(),p[i].y=read();
    	graham();
    	q[m+1]=q[1];
    	for(int i=1,j=1;i<=m;i++){
    		while((nxt(j)!=i)&&sign((area(q[i],q[i+1],q[j+1])-area(q[i],q[i+1],q[j])))>=0)j=nxt(j);//注意判边界
    		ans=max(ans,(q[j]-q[i]).calc());
    		ans=max(ans,(q[j]-q[i+1]).calc());//似乎不加这句话过不了…,反正加了不会错
    	}
    	cout<<ans<<'
    ';
    }
    

    半平面交

    (BZOJ2618)

    point a[N],b[N];
    line p[N],q[N];
    inline point insec(const line &a,const line &b){
        double t1=(b.s-a.s)*(a.e-a.s),t2=(a.e-a.s)*(b.e-a.s);
        double k=(t1)/(t1+t2);
        return (b.s+((b.e-b.s)*k));
    }
    inline double K(int i){
    	return (q[i].e.y-q[i].s.y)/(q[i].e.x-q[i].s.x);
    }
    inline double B(int i){
    	return q[i].s.y-K(i)*q[i].s.x;
    }
    inline bool comp(const line &a,const line &b,const line &c){
        return sign((c.e-c.s)*(insec(a,b)-c.s))<0;
    }
    int hd,tl,tot,n,m;
    int ans[N];
    inline void half(){
        sort(p+1,p+n+1);
        for(int i=1;i<=n;i++){
            if(sign(p[i].rad-p[i-1].rad))tot++;
            p[tot]=p[i];
        }
        q[1]=p[1],q[2]=p[2],hd=1,tl=2;
        for(int i=3;i<=tot;i++){
            while(hd<tl&&comp(q[tl-1],q[tl],p[i]))tl--;  //注意先tail后head不能反    
            while(hd<tl&&comp(q[hd],q[hd+1],p[i]))hd++;
            q[++tl]=p[i];
        }
        while(hd<tl&&comp(q[tl-1],q[tl],q[hd]))tl--;
        while(hd<tl&&comp(q[hd],q[hd+1],q[tl]))hd++;
        tot=0,q[tl+1]=q[hd];
        for(int i=hd;i<=tl;i++)b[++tot]=insec(q[i],q[i+1]);
    }
    inline double area(){
        double res=0;
        for(int i=1;i<=tot;i++){
            res+=b[i]*b[i%tot+1];
        }
        return res/2;
    }
    int main(){
        m=read();
        for(int i=1;i<=m;i++){
            int k=read();
            for(int j=1;j<=k;j++)a[j].x=read(),a[j].y=read();
            for(int j=1;j<=k;j++)p[++n]=line(a[j],a[j%k+1]);
        }
        half();
        printf("%.3lf",area());
    }
    

    经典题目

    动态凸包

    最小矩阵覆盖

    圆的周长并

    圆的凸包(等周长)

    最小圆覆盖

  • 相关阅读:
    装饰器的进阶
    Django admin组件应用
    AJAX
    Cookie、Session和自定义分页
    Django中ORM介绍和字段及字段参数
    Django 框架
    Django之视图
    Django之路由系统
    Django ORM相关操作
    Django 模板语言
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145561.html
Copyright © 2011-2022 走看看