1. 程式人生 > >luogu P4423 [BJWC2011]最小三角形

luogu P4423 [BJWC2011]最小三角形

傳送門

資料範圍n<=200000

類似平面最近點對的題

我們考慮平面最近點對的實現過程

二分的時候其實開了一個tmp陣列存可能與列舉的點成為答案的點

而且一個非常優秀的性質就是元素個數是常數

所以這裡同樣沿用 tmp存到中線距離<=答案/2的點

因為大於答案/2的話一定總周長是更大的

剩下的和板子一樣了

(然後我這裡沒用歸併排序嚶嚶嚶)

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<queue>
 6
#include<iostream> 7 #define B puts("GGGGGGG"); 8 #define ms(a,b) memset(a,b,sizeof a) 9 #define rep(i,a,n) for(int i = a;i <= n;i++) 10 #define per(i,n,a) for(int i = n;i >= a;i--) 11 #define inf 2147483647 12 using namespace std; 13 typedef long long ll; 14 ll read() { 15 ll as = 0
,fu = 1; 16 char c = getchar(); 17 while(c < '0' || c > '9') { 18 if(c == '-') fu = -1; 19 c = getchar(); 20 } 21 while(c >= '0' && c <= '9') { 22 as = as * 10 + c - '0'; 23 c = getchar(); 24 } 25 return as * fu; 26 } 27 const int
N = 200003; 28 //head 29 typedef double D; 30 int n; 31 struct point { 32 D x,y; 33 point operator - (const point &a) const { 34 return (point){x - a.x,y - a.y}; 35 } 36 D len() {return sqrt(x*x+y*y);} 37 }p[N]; 38 bool cmpx(point x,point y) { 39 return x.x < y.x; 40 } 41 bool cmpy(point x,point y) { 42 return x.y < y.y; 43 } 44 45 //[l,r) 46 D solve(int l,int r) { 47 if(r - l <= 1) return inf; 48 if(r - l == 2) { 49 // res[l][r] = (ans){p[l],p[l+1],p[r]}; 50 return (p[l+1] - p[l]).len() + (p[r] - p[l+1]).len() + (p[r] - p[l]).len(); 51 } 52 int m = l+r >> 1; 53 D midx = (p[m].x + p[m-1].x) / 2.0; 54 D d = min(solve(l,m),solve(m,r)); 55 // D d1 = solve(l,m),d2 = solve(m,r),d; 56 // if(d1 < d2) res[l][r] = res[l][m],d = d1; 57 // else res[l][r] = res[m][r],d = d2; 58 D lim = d / 2.0; 59 static point tmp[N]; 60 int top = 0; 61 rep(i,l,r - 1) if(fabs(p[i].x - midx) <= lim) tmp[++top] = p[i]; 62 sort(tmp+1,tmp+1+top,cmpy); 63 int cur = 1; 64 rep(i,1,top) { 65 while(cur <= top && fabs(tmp[i].y - tmp[cur].y) <= lim) cur++; 66 rep(u,i+1,cur-1) rep(v,i+1,u-1) { 67 // if((tmp[i] - tmp[u]).len() + (tmp[i] - tmp[v]).len() + (tmp[u] - tmp[v]).len() < d) res[l][r] = (ans){p[v],p[u],p[i]}; 68 d = min(d,(tmp[i] - tmp[u]).len() + (tmp[i] - tmp[v]).len() + (tmp[u] - tmp[v]).len()); 69 } 70 } 71 return d; 72 } 73 74 int main() { 75 // freopen("in.in","r",stdin); 76 n = read(); 77 rep(i,1,n) scanf("%lf%lf",&p[i].x,&p[i].y); 78 sort(p+1,p+n+1,cmpx); 79 printf("%.6f\n",solve(1,n+1)); 80 // printf("%lf %lf %lf %lf %lf %lf\n",res[1][n+1].a.x,res[1][n+1].a.y,res[1][n+1].b.x,res[1][n+1].b.y,res[1][n+1].c.x,res[1][n+1].c.y); 81 // rep(i,1,n) printf("%.2lf %.2lf\n", p[i].x,p[i].y); 82 return 0; 83 }