水题:注意题目上面有一个至少离城堡的距离为L,其实思考一下就知道是指离凸包(凸多边形)的距离为L,这时很容易知道外围的圆的圆心角叠加之后就是一个整圆;和poj2187一样使用graham形成凸包;还有就是开始我四舍五入用floor(),却使用%d输出,导致一直输出是0;因为floor()的返回值也是浮点型。。。
#include<iostream> #include<cstdio> #include<cstring> #include<string.h> #include<algorithm> #include<map> #include<queue> #include<vector> #include<cmath> #include<stdlib.h> #include<time.h> using namespace std; const double PI = acos(-1.0); const int MAXN = 5e4+10; struct point{ int x,y; point(){} point(int _x,int _y){ x = _x; y = _y; } int operator *(const point &b)const{ return (x*b.y - y*b.x); } point operator -(const point &b)const{ return point(x - b.x,y - b.y); } void input(){ scanf("%d%d",&x,&y); } }p[MAXN]; int dist2(point a,point b) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } bool cmp(point a,point b) // 正表示逆时针,返回true表示不要交换; { int cp = (a-p[0])*(b-p[0]); if(cp < 0) return false; if(cp == 0 && (dist2(a,p[0]) >= dist2(b,p[0])) ) return false; return true; } int stk[MAXN],top; void graham(int n) // 形成凸包; { int i; stk[0] = 0;stk[1] = 1; top = 1; for(i = 2;i < n;i++){ // 构造一个逆时针旋转的单调栈; while(top > 0 && (p[stk[top]] - p[stk[top-1]])*(p[i] - p[stk[top-1]]) <= 0) top--; stk[++top] = i; } stk[++top] = 0;//为了下面%top,很容易知道n-1号元素一定在凸包里面; /*for(i=0;i<n;i++) printf("**%d %d ",p[i].x,p[i].y); printf(" %d ",top); // 0 ~ top - 1; for(i=0;i<top;i++) printf("**%d %d ",p[stk[i]].x,p[stk[i]].y);*/ } double solve() { double ans = 0; for(int i = 0;i < top;i++){ ans += sqrt(1.*dist2(p[stk[i]],p[stk[i+1]])); } return ans; } int main() { int i,n,L; while(scanf("%d%d",&n,&L) == 2){ for(i = 0;i < n;i++) p[i].input(); int st = 0; for(i = 1;i < n;i++) // 选出起始点; if(p[st].y > p[i].y||(p[st].y == p[i].y && p[st].x > p[i].x)) st = i; swap(p[0],p[st]); sort(p+1,p+n,cmp);// 以p[0]为参考点逆时针极角由进到远排序; graham(n); printf("%d ",int(solve() + PI*2*L + 0.5)); } return 0; }