http://poj.org/problem?id=1113
Time Limit:1000MS | Memory Limit:10000K | |
Total Submissions:16323 | Accepted:5243 |
Description

Your task is to help poor Architect to save his head, by writing a program that will find the minimum possible length of the wall that he could build around the castle to satisfy King's requirements.
The task is somewhat simplified by the fact, that the King's castle has a polygonal shape and is situated on a flat ground. The Architect has already established a Cartesian coordinate system and has precisely measured the coordinates of all castle's vertices in feet.
Input
Next N lines describe coordinates of castle's vertices in a clockwise order. Each line contains two integer numbers Xi and Yi separated by a space (-10000 <= Xi, Yi <= 10000) that represent the coordinates of ith vertex. All vertices are different and the sides of the castle do not intersect anywhere except for vertices.
Output
Sample Input
9 100 200 400 300 400 300 300 400 300 400 400 500 400 500 200 350 200 200 200
Sample Output
1628
凸包周长+圆的周长=围墙的周长
刚刚开始结果用float表示总是WA,换成double后AC!
/* Author : yan * Question : * Date && Time : * Compiler : gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3 */ #include <stdio.h> #define N 1005 #define inf 1e-8 #define PI 3.141592653589793 typedef struct { int x; int y; }point; point points[N]; //点集 point chs[N]; //栈 int sp; //栈顶指针 //计算两点之间距离 double dis(point a, point b) { return sqrt((a.x - b.x) * (a.x - b.x) * 1.0 + (a.y - b.y) * (a.y - b.y)); } //通过矢量叉积求极角关系(p0p1)(p0p2) //k > 0 ,p0p1在p0p2顺时针方向上 double multi(point p0, point p1, point p2) { return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y); } int cmp(const void *p, const void *q) { point a = *(point *)p; point b = *(point *)q; double k = multi(points[0], a, b); if(k < -inf) return 1; else if(fabs(k) < inf && (dis(a, points[0]) - dis(b, points[0])) > inf) //两点在同一直线上的话,用最近的 return 1; else return -1; } void convex_hull(int n) { int i, k, d; int miny = points[0].y, index = 0; for(i=1; i<n; i++) //找最左下顶点 { if(points[i].y < miny) //找到y坐标最小的点 { miny = points[i].y; index = i; } else if(points[i].y == miny && points[i].x < points[index].x) //相同的话找到x最小的 { index = i; } } //把最左下顶点放到第一个 point temp; temp = points[index]; points[index] = points[0]; points[0] = temp; qsort(points+1, n-1, sizeof(points[0]), cmp); //p[1:n-1]按相对p[0]的极角从小到大排序 chs[0] = points[n-1]; chs[1] = points[0]; sp = 1; k = 1; while(k <= n-1) { double d = multi(chs[sp], chs[sp-1], points[k]); if(d <= 0) { sp++; chs[sp] = points[k]; k++; } else sp--; } } int main() { int i,n,dist; double sum; //freopen("input", "r", stdin); scanf("%d %d", &n,&dist); for(i=0; i<n; i++) scanf("%d %d",&points[i].x,&points[i].y); convex_hull(n); sum = 0; for(i=1; i<=sp; i++) //求周长 sum += dis(chs[i-1], chs[i]); sum += dis(chs[0], chs[sp]); printf("%d",(int)(sum+2*PI*dist+0.5)); return 0; }