zoukankan      html  css  js  c++  java
  • HDU 4667 Building Fence(求凸包的周长)

    题目链接:传送门 


    题意:

    给定n个圆。m个三角形求把这些图形所有覆盖的图形的最小的周长。


    分析:

    刚開始看到就想到了求凸包,但是圆怎么求了?就暴力把圆切割成1000个点然后求凸包就能够了。

    水过了。正解是找圆与圆的切点圆与三角形上的点与圆引得切线的切点。


    代码例如以下:

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    using namespace std;
    
    typedef long long LL;
    
    const double eps = 1e-10;
    
    const int maxn = 1e6+10;
    
    const double pi = acos(-1.0);
    
    const double inf = 1e17;
    
    int dcmp(double x){
        if(fabs(x)<eps) return 0;
        if(x>0) return 1;
        return -1;
    }
    
    struct point{
        double x,y;
        int id;
        point(){}
        point(double _x,double _y,int i):x(_x),y(_y),id(i){}
        bool operator <(const struct point &tmp)const{
            if(dcmp(x-tmp.x)==0) return dcmp(y-tmp.y)<0;
            return dcmp(x-tmp.x)<0;
        }
        bool operator == (const struct point &tmp)const{
            return dcmp(x-tmp.x)==0&&dcmp(y-tmp.y)==0;
        }
    }p[maxn],st[maxn];
    
    double Cross(point a,point b,point c){
        return (c.x-a.x)*(b.y-a.y) - (b.x-a.x)*(c.y-a.y);
    }
    
    int ConvexHull(point *p,int n,point *st){
        sort(p,p+n);
        n=unique(p,p+n)-p;
        int m=0;
        for(int i=0; i<n; i++) {
            while(m>1&&Cross(st[m-2],p[i],st[m-1])<=0) m--;
            st[m++]=p[i];
        }
        int k=m;
        for(int i=n-2; i>=0; i--){
            while(m>k&&Cross(st[m-2],p[i],st[m-1])<=0)m--;
            st[m++]=p[i];
        }
        if(n>1) m--;
        return m;
    }
    
    double dis(point a,point b){
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    
    int R[600];
    
    int main()
    {
        int n,m;
        while(~scanf("%d%d",&n,&m)){
            int cnt = 0;
            for(int i=0;i<n;i++){
                double x,y,r;
                scanf("%lf%lf%lf",&x,&y,&r);
                R[i]=r;
                for(int j=0;j<1000;j++){
                    double tmp = 2*pi*j/1000;
                    p[cnt++]=point(x+r*cos(tmp),y+r*sin(tmp),i);
                }
            }
            for(int i=0;i<m*3;i++){
                double x,y;
                scanf("%lf%lf",&p[cnt].x,&p[cnt].y);
                p[cnt].id=cnt++;
            }
            int num = ConvexHull(p,cnt,st);
            double ans = 0;
            for(int i=0;i<num;i++){
                int t1 = st[i].id;
                int t2 = st[(i+1)%num].id;
                if(t1==t2){
                    ans+=pi*2*R[t1]/1000;
                }
                else ans+=dis(st[i],st[(i+1)%num]);
            }
            printf("%.4lf
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    希尔排序
    插入排序
    Unity创建一个简易的弹簧(弹动)效果
    看到个美到爆的菜单,忍不住扒下来~
    用avalon实现一个完整的todomvc(带router)
    页面动态加入<script>标签并执行代码
    一个简单粗暴的前后端分离方案
    常用的HTML5、CSS3新特性能力检测写法
    犀利的background-clip:text,实现K歌字幕效果
    用canvas开发H5游戏小记
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6979129.html
Copyright © 2011-2022 走看看