看论文的时候看到的题,给你一个多边形,需要用最少的离这个多边形远为L的墙围住。凸包的话是距离最短的。画图的话,可知,拐角部分都是圆弧,整个一周下来正好是半径为L的圆的周长。所以结果就是凸包周长+圆周长。
我发现死活过不去,然后看人家的排序,我没有判断距离,改了改,居然过了><。。。难道我以前写的凸包排序都是错的??!!、、、好恐怖。。。记住了。。
#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> using namespace std; const int MAX = 1010; const double eps = 1e-10; const double pi = acos(-1.0); typedef struct Point{ double x,y; }Point; Point c[MAX]; bool dy(double x,double y) // x > y { return x > y + eps; } bool xy(double x,double y) // x < y { return x < y - eps; } bool dyd(double x,double y) // x >= y { return x > y - eps; } bool xyd(double x,double y) // x <= y { return x < y + eps; } bool dd(double x,double y) // x == y { return fabs( x - y ) < eps; } double crossProduct(Point a,Point b,Point c)//向量 ac 在 ab 的方向 { return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y); } double Distance(Point a,Point b) // a b 两点之间的距离 { return sqrt( ( a.x - b.x ) * ( a.x - b.x ) + ( a.y - b.y ) * ( a.y - b.y ) ); } bool cmp(Point a,Point b) // 第一次排序 { if( dd(a.y ,b.y ) ) return xy(a.x, b.x); return xy(a.y,b.y); } bool cmp1(Point a,Point b) // 第二次排序 { double len = crossProduct(c[0],a,b); if( dd(len,0.0) ) return xy(Distance(c[0],a),Distance(c[0],b)); return xy(len,0.0); } double circum(double r) { return 2 * pi * r; } Point stk[MAX]; int top; double dis() { double sum = 0.0; for(int i=0; i<top; i++) sum += Distance(stk[i],stk[i+1]); sum += Distance(stk[0],stk[top]); return sum; } double Graham(int n) { sort(c,c+n,cmp); sort(c+1,c+n,cmp1); top = 0; stk[top++] = c[0]; stk[top++] = c[1]; stk[top++] = c[2]; top--; for(int i=3; i<n; i++) { while(1) { Point a,b; a = stk[top]; b = stk[top-1]; if( xyd( crossProduct(a,b,c[i]), 0.0 ) ) top--; else break; } stk[++top] = c[i]; } return dis(); } int main() { int ncases; int n,l; scanf("%d",&ncases); while( ncases-- ) { scanf("%d %d",&n,&l); for(int i=0; i<n; i++) scanf("%lf %lf",&c[i].x,&c[i].y); double ans = Graham(n); double len = circum(l); printf("%.0lf/n",(ans+len)); if( ncases ) printf("/n"); } return 0; }