zoukankan      html  css  js  c++  java
  • 【BZOJ282】【洛谷P3829 】【SHOI2012】—信用卡凸包(凸包)

    传送门

    可以发现答案就是所有信用卡四个角的圆心做出来的凸包加上一个整的圆的周长

    证明?

    由于直线的斜率不会变,所以只有可能在圆的边上绕的时候改变
    把所有圆围起来就是一个整圆了

    剩下的在边上和圆心无所谓(思考)

    然后凸包就完了

    关于向量旋转角度的变换随便找一篇blogblog或者手推一下就出来了

    #include<bits/stdc++.h>
    using namespace std;
    #define eps 1e-8
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
    	return res*f;	
    } 
    const int N=40005;
    const double pi=acos(-1.0);
    struct point{
    	double x,y;
    	point(double a=0,double b=0){
    		x=a,y=b;
    	}
    	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 double operator *(const point &a,const point &b){
    		return a.x*b.y-a.y*b.x;
    	}
    	inline double calc()const{
    		return x*x+y*y;
    	}
    }p[N],q[N];
    inline point rotate(point a,double rad){
    	return point(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
    }
    int n,num,m;
    double a,b,r,ans;
    inline bool comp(const point &a,const point &b){
    	double res=(a-p[1])*(b-p[1]);
    	if(res!=0)return res>0;
    	return (a-p[1]).calc()<(b-p[1]).calc();
    }
    inline void graham(){
    	int pt=1;
    	for(int i=2;i<=num;i++){
    		if(p[i].x<p[pt].x||p[i].x==p[pt].x&&p[i].y<p[pt].y)pt=i;
    	}
    	if(pt!=1)swap(p[pt],p[1]);
    	sort(p+2,p+num+1,comp);
    	q[++m]=p[1];
    	for(int i=2;i<=num;i++){
    		while(m>=3&&(p[i]-q[m-1])*(q[m]-q[m-1])>=0)m--;
    		q[++m]=p[i];
    	}
    }
    int main(){
    	n=read();
    	scanf("%lf%lf%lf",&a,&b,&r);
    	a-=2*r,b-=2*r;
    	for(int i=1;i<=n;i++){
    		double x,y,rad;
    		scanf("%lf%lf%lf",&x,&y,&rad);
    		point k(x,y),d,v;
    		d=point(x+b/2,y-a/2),v=rotate(k-d,rad),p[++num]=k+v;
    		d=point(x-b/2,y-a/2),v=rotate(k-d,rad),p[++num]=k+v;
    		d=point(x+b/2,y+a/2),v=rotate(k-d,rad),p[++num]=k+v;
    		d=point(x-b/2,y+a/2),v=rotate(k-d,rad),p[++num]=k+v;
    	}
    	graham();
    	for(int i=2;i<=m;i++)
    	ans+=sqrt((q[i]-q[i-1]).calc());
    	ans+=sqrt((q[1]-q[m]).calc());
    	ans+=2*pi*r;
    	printf("%.2lf",ans);
    }
  • 相关阅读:
    Qt发送事件与自定义事件
    Qt文本流和数据流
    Qt文件操作
    Qt 布局管理器
    Qt 标准对话框
    Qt 对话框QDailog及其类型
    Qt 对象间的父子关系
    Qt 信号与槽
    Qt 计算器界面实现
    C++ 多态、虚函数(virtual 关键字)、静态联编、动态联编
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145670.html
Copyright © 2011-2022 走看看