http://acm.hust.edu.cn/vjudge/contest/130303#problem/Eios
http://7xjob4.com1.z0.glb.clouddn.com/4c9abc79e61f4d543441b48cb0cf6bbe
less
The input file contains several test cases, each of them as described below.
The first line contains integer N — the number of points placed by Peter (1 ≤ N ≤ 100000). Each of
following N lines contains two integers xi , yi — the point coordinates placed by Peter. The coordinates by absolute value do not exceed 10^6 . Some points can match.
ui
For each test case, you need to print one number — the perimeter of the required polygon, on a line
by itself. The answer should be printed with accuracy not less than 0.001.
spa
1 0 0 2 1 1 1 2
5.656 7.656854
2016-HUST-線下組隊賽-4
code
給出網格上的n個點,求一個周長最小的多邊形使得全部點都在其內部,且多邊形的邊要麼是網格的邊,要麼是網格的對角線.
ip
因爲邊只能是網格邊或者對角線,在紙上畫一下三角形時的狀況便可推出結果輪廓.
先對全部點求一個凸包,而後把凸包拓展成爲由網格邊或對角線組成的多邊形,再總體往外擴大1便是最後的結果.
get
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <algorithm> #include <vector> #include <map> #include <set> #include <queue> #include <stack> #define LL long long #define maxn 111000 #define inf 0x3f3f3f3f #define mod 1000000007 #define mid(a,b) ((a+b)>>1) #define eps 1e-8 #define IN freopen("in.txt","r",stdin); using namespace std; int n; struct Point{ LL x,y; Point() {} Point(LL tx, LL ty) {x=tx;y=ty;} }p[maxn]; LL xmul(Point p0, Point p1, Point p2) { return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y); } LL Dis(Point p1, Point p2) { return (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y); } int s[maxn], top; int cmp_polar(Point p1, Point p2) { LL tmp = xmul(p[0], p1, p2); if(tmp > 0) return 1; else if(tmp==0 && (Dis(p[0],p1)-Dis(p[0],p2))<0) return 1; else return 0; } void polar(int n) { int pos = 0; Point p0 = p[0]; for(int i=1; i<n; i++) { if(p0.y>p[i].y || (p0.y==p[i].y && p0.x>p[i].x)) { p0 = p[i]; pos = i; } } p[pos] = p[0]; p[0] = p0; sort(p+1, p+n, cmp_polar); } void Gramham(int n) { polar(n); top = 0; for(int i=0; i<n; i++) { while(top>1 && xmul(p[s[top-2]],p[s[top-1]],p[i])<=0) top--; s[top++] = i; } } int main() { //IN; while (scanf("%d", &n) != EOF) { for(int i=0; i<n; i++) { scanf("%I64d %I64d", &p[i].x, &p[i].y); } Gramham(n); LL ans1 = 0, ans2 = 0; for(int i=0; i<top; i++) { Point p1, p2; p1 = p[s[i]]; if(i<top-1) p2 = p[s[i+1]]; else p2 = p[s[0]]; LL dx = abs(p1.x - p2.x); LL dy = abs(p1.y - p2.y); ans1 += abs(dx - dy); ans2 += min(dx, dy); } ans2 += 4; double ans = 1.0*ans1 + sqrt(2.0)*(double)ans2; printf("%f\n", ans); } return 0; }