PS: 次題目雖然敘述點的個數大於等於3但是並不保證凸包是否存在,所以還要判斷一下。經常刷題的孩紙可能會遇到用C++ 可用AC的題目用G++ 卻 Wrong Answer. 思考過為什麼嗎? 對於double 類型用%lf 輸入用%lf輸出是window 環境下VC的標准但不是真正的標准,對於double 類型 真正的標准是用%lf輸入,用%f輸出。所以把%.0lf改為%.0f 在G++環境下面就可用輕松AC了。
還有%lld 和 %I64d, 同時也學習一下控制精度的技巧,比如 printf("%d\n", (int)(ans+0.5)). 設置雙精度下的畢竟函數等。
#include#include #include #include #include #include using namespace std; const double eps = 1e-8; const double pi = acos(-1.0); const int maxn = 1010; struct point { double x, y; point(double x=0, double y=0):x(x),y(y) {} }; int sign(double x) { if(fabs(x) 0 ? 1 : -1; } point operator - (point A, point B) { return point(A.x-B.x, A.y-B.y); } double Cross(point A, point B) { return A.x*B.y - A.y*B.x; } double mul(point P, point B, point C) { return Cross(B-P, C-P); } double dis2(point A, point B) { return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y); } double dis(point A, point B){ double t1 = (A.x-B.x)*(A.x-B.x); double t2 = (A.y-B.y)*(A.y-B.y); return sqrt(t1+t2); } int n, l; point p[maxn], q[maxn]; point s; // original. bool cmp(point A, point B) { if(sign(mul(s, A, B))>0) return true; else if(sign(mul(s, A, B))==0 && dis2(s,A) < dis2(s, B)) return true; else return false; } int convex_hull(point *a, int n, point *b) { for(int i = 1; i < n; i++) { if(sign(a[i].x-a[0].x)<0 || (sign(a[i].x-a[0].x)==0 && sign(a[i].y-a[0].y)<0)) { swap(a[0],a[i]); } } s = a[0]; sort(a, a+n, cmp); int newn = 2; b[0]=a[0], b[1]=a[1]; for(int i = 2; i < n; i++) { while(newn>1 && sign(mul(b[newn-1], b[newn-2], a[i]))>=0) --newn; b[newn++] = a[i]; } return newn; } int main() { scanf("%d%d", &n, &l); for(int i = 0; i < n; i++) { scanf("%lf%lf", &p[i].x, &p[i].y); } int len = convex_hull(p, n, q); if(len < 3) { printf("0\n"); return 0; } q[len] = q[0]; double ans = 0; for(int i = 0; i < len; i++) { ans += dis(q[i], q[i+1]); } ans += 2*pi*l; printf("%.0f\n", ans); #ifdef M printf("%.0f\n", ans); // G++ AC,C++ AC。 printf("%d\n",(int)(ans+0.5)); G++ AC. printf("%.0lf\n", ans); C++ AC, G++ WA. #endif return 0; }