POJ 1113 Wall (凸包)

題目鏈接:http://poj.org/problem?id=1113




題解:(盜一張圖)結合上圖, 就能很明顯的看出這道題的關鍵就是求出凸包。

     結果等於:一個凸包的周長+以L爲半徑的圓的周長。





#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define N 1111
#define PI 3.141592653
//定義點
struct Point
{
	double x, y;
	Point(double x = 0, double y = 0) : x(x), y(y) {}
};
typedef Point Vector; //Vector 爲 Point的別名

Vector operator - (Point A, Point B) {return Vector(A.x-B.x, A.y-B.y);}

double Dot(Vector A, Vector B){return A.x*B.x + A.y*B.y;}
double Length(Vector A){return sqrt(Dot(A, A));}
double Cross(Vector A, Vector B){return A.x*B.y - A.y*B.x;}
bool cmp ( Point a, Point b )
{
    if ( a.x != b.x ) return a.x < b.x;
    else return a.y < b.y;
}
int ConvexHull(Point *p, int n, Point * ch)
{
	sort(p, p+n, cmp); //先比較x座標,在比較y座標
	int m = 0;
	for(int i = 0; i < n; i++)
	{
		while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
		ch[m++] = p[i];
	}

	int k = m;
	for(int i = n-2; i >= 0; i--)
	{
		while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
		ch[m++] = p[i];
	}
	if(n > 1) m--;
	return m;
}

int main ()
{
    Point point[N], tu[N];
    int n, l;
    scanf("%d %d", &n, &l);

    for(int i = 0; i < n; i++)
        scanf("%lf %lf", &point[i].x, &point[i].y);

    int cnt = ConvexHull(point, n, tu);

    double ans = 2*PI*l + Length(tu[cnt]-tu[0]);

    for(int i = 1; i <= cnt; i++)
        ans += Length(tu[i]-tu[i-1]);

    printf("%d\n", int(ans+0.5));
    return 0;
}


發佈了121 篇原創文章 · 獲贊 10 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章