#include <stdio.h>#include <stdlib.h>#include <math.h>#include <conio.h>#define N 200#define inf 1e-6typedef struct{ double x; double 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; double miny = points[0].y; int 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, j, n; double sum, area; while(1) { scanf("%d",&n); if(n==0)break; for(i=0; i<n; i++) scanf("%lf%lf", &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("周長:%.4f\n", sum); area = 0.; for(i=1; i<sp; i++) {//求面積 double k = multi(chs[0], chs[i], chs[i+1]); //三角形面積是向量叉積的1/2 area += k; } area = fabs(area) / 2; printf("面積:%.4f\n", area); } return 0;}