2013 多校第七场 hdu 4667 Building Fence(计算几何、凸包)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4667

题目大意:给你n个圆,m个三角形,两两不重叠,问你把他们全都围起来的最短的篱笆的长度。

思路:我的做法是暴力,三角形不用处理,因为就三个点,圆的话,直接枚举角度,把它拆成点,然后上凸包,飘时限和精度。。。

经过不懈的努力之后,终于用G++ 900ms+ 飘过了,补充一句,C++TLE。。 = =

比赛的时候剩下一个半小时搞这道,因为搞计算几何的队友不在,木有搞过计算几何,也木有模板,明确暴力的思路后,就去网上乱找模板,结果找 cuo 了,最后还是没A。。 T^T

暴力代码如下:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const double eps = 1e-8;
const double PI = acos(-1.0);

const int MAXN = 11111111 ;

struct Point {
    double x, y;
    Point(){}
    Point(double a,double b): x(a),y(b) {}
    Point operator - (const Point& t) const {
        Point tmp;
        tmp.x = x - t.x;
        tmp.y = y - t.y;
        return tmp;
    }
    Point operator + (const Point& t) const {
        Point tmp;
        tmp.x = x + t.x;
        tmp.y = y + t.y;
        return tmp;
    }
    bool operator == (const Point& t) const {
        return fabs(x-t.x) < eps && fabs(y-t.y) < eps;
    }
}GP,point[MAXN];
struct Cir {
	Point ct;
    double r;
};

inline double Cross(Point a, Point b, Point c) {					// 叉积
	return (b.x-a.x)*(c.y-a.y) - (c.x-a.x)*(b.y-a.y);
}
inline double PPdis(Point a, Point b) {								// 点点距离
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
inline double PLdis(Point p,Point l1,Point l2){						// 点线距离
	return fabs(Cross(p,l1,l2))/PPdis(l1,l2);
}
inline bool same_dir(Point a, Point b) {							// 向量是否同向
    return fabs(a.x*b.y-b.x*a.y) < eps && a.x*b.x > -eps && a.y*b.y > -eps;
}
bool dotOnSeg(Point p, Point s, Point e) {							// 点是否在线段上
    if ( p == s || p == e )		// 看具体情况端点是否合法
        return true;
    return fabs((p-s).x*(p-e).y - (p-e).y*(p-s).x) < eps &&
        (p.x-s.x)*(p.x-e.x)<eps && (p.y-s.y)*(p.y-e.y)<eps;
}
bool Intersect(Point p1, Point p2, Point p3, Point p4, Point& p) {	// 直线相交
	double a1, b1, c1, a2, b2, c2, d;
	a1 = p1.y - p2.y; b1 = p2.x - p1.x; c1 = p1.x*p2.y - p2.x*p1.y;
	a2 = p3.y - p4.y; b2 = p4.x - p3.x; c2 = p3.x*p4.y - p4.x*p3.y;
	d = a1*b2 - a2*b1;
	if ( fabs(d) < eps )	return false;
	p.x = (-c1*b2 + c2*b1) / d;
	p.y = (-a1*c2 + a2*c1) / d;
	return true;
}
bool cmpyx(Point a, Point b) {
	if ( a.y != b.y )
		return a.y < b.y;
	return a.x < b.x;
}
void Grahamxy(Point *p, int &n) {									// 水平序(住:两倍空间)
	if ( n < 3 )
		return;
	int i, m=0, top=1;
	sort(p, p+n, cmpyx);
	for (i=n; i < 2*n-1; i++)
		p[i] = p[2*n-2-i];
	for (i=2; i < 2*n-1; i++) {
		while ( top > m && Cross(p[top], p[i], p[top-1]) < eps )
			top--;
		p[++top] = p[i];
		if ( i == n-1 )	m = top;
	}
	n = top;
}

bool cmpag(Point a, Point b) {
    double t = (a-GP).x*(b-GP).y - (b-GP).x*(a-GP).y;
    return fabs(t) > eps ? t > 0 : PPdis(a, GP) < PPdis(b, GP);
}
void Grahamag(Point *p, int &n) {								// 极角序
    int i, top = 1;
    GP = p[0];
    for (i=1; i < n; i++) if(p[i].y<GP.y-eps || (fabs(p[i].y-GP.y)<eps && p[i].x<GP.x)) {
        GP = p[i];
    }
    sort(p, p+n, cmpag);
    for ( i=2; i < n; i++ ) {
        while ( top > 0 &&  Cross(p[top], p[i], p[top-1]) < eps )
            top--;
        p[++top] = p[i];
    }
    p[++top] = p[0];
    n = top;
}

int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        int tot = 0;
        double x,y,r;
        for(int i = 0;i<n;i++)
        {
            scanf("%lf%lf%lf",&x,&y,&r);
            for(double j = 0;j<2*PI;j += 0.0032)
            {
                point[tot++] = Point(x+r*cos(j),y+r*sin(j));
            }
        }
        for(int i = 0;i<m;i++)
            for(int j = 0;j<3;j++)
            {
                scanf("%lf%lf",&x,&y);
                point[tot++] = Point(x,y);
            }
        Grahamxy(point,tot);
        /*
        printf("tot = %d\n",tot);
        for(int i = 0;i<tot;i++)
            printf("i = %d,x = %lf,y = %lf\n",i,point[i].x,point[i].y);
        */
        double ans = 0;
        Point pre = point[0];
        for(int i = 1;i<tot;i++)
        {
            ans += PPdis(point[i],pre);
            pre = point[i];
        }
        ans += PPdis(point[0],pre);
        printf("%.5f\n",ans);
    }
    return 0;
}



你可能感兴趣的:(2013 多校第七场 hdu 4667 Building Fence(计算几何、凸包))