1. 程式人生 > >傻逼數學題(math)

傻逼數學題(math)

ima 16px name freopen efi include 沒有 約定 描述

傻逼數學題
題目描述

由於亂碼,復制不下來,只好截圖了

技術分享圖片

輸入格式

第一行一個正整數n

接下來n行每行兩個整數x,y,表示第i個點的坐標

輸出格式

一行一個數表示最小距離和,保留6位小數

樣例輸入

4

1 1

2 3

3 3

3 4

樣例輸出

3.414214

樣例解釋

技術分享圖片

數據約定

對於30%的數據,n<=400.

對於100%的數據,3<=n<=200000.

反思

這一題其實算是個原題了,就是昨天的最近點對,只不過我們需要尋找的變成了3個,思路都是差不多的,但是我就是覺得太復雜,所以沒有去實現.所以在考場上我就只打了一個n三方的暴力,也就只拿了30pts,所以我們有任務千萬別拖欠,一朝拖欠,就要付出慘痛的代價......

思路

就是原題啦,我們只需要在最近點對的基礎改幾個地方

1.邊界條件(l+2==r)因為有3個

2.在越過中間尋找時,註意3重循環

代碼
技術分享圖片
 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define FOR(i,a,b) for(register int i=a;i<=b;i++)
 4 #define ROF(i,a,b) for(register int i=a;i>=b;i--)
 5 using namespace std;
 6 int n;
 7 const ll N=1000000000000;
 8 int tmpt[200100
]; 9 struct ss 10 { 11 double x;double y; 12 }pot[200100]; 13 int scan() 14 { 15 int as=0,f=1; 16 char c=getchar(); 17 while(c>9||c<0){if(c==-) f=-1;c=getchar();} 18 while(c>=0&&c<=9){as=(as<<3)+(as<<1)+c-0;c=getchar();} 19 return as*f; 20 }
21 bool cmp(ss i,ss j) 22 { 23 return i.x<j.x; 24 } 25 bool cmp2(int i,int j) 26 { 27 return pot[i].y<pot[j].y; 28 } 29 double dis(int i,int j) 30 { 31 double f=sqrt(double((pot[i].x-pot[j].x)*(pot[i].x-pot[j].x)+(pot[i].y-pot[j].y)*(pot[i].y-pot[j].y))); 32 return f; 33 } 34 double par(int l,int r) 35 { 36 // cout<<"y"<<endl; 37 double d=N; 38 if(l==r||l+1==r) return d; 39 if(l+2==r) return dis(l,r)+dis(l+1,r)+dis(l+1,l); 40 int mid=(l+r)>>1;//除以2 41 double d1=par(l,mid); 42 double d2=par(mid+1,r); 43 d=min(d1,d2); 44 int k=0; 45 FOR(i,l,r) 46 { 47 if(abs(pot[i].x-pot[mid].x)<=d) 48 { 49 tmpt[++k]=i;//保存位置 50 } 51 } 52 sort(tmpt+1,tmpt+k+1,cmp2); 53 FOR(i,1,k) 54 { 55 FOR(j,i+1,k) 56 { 57 if(pot[tmpt[j]].y-pot[tmpt[i]].y>=d/2) break; 58 FOR(j1,j+1,k) 59 { 60 if(pot[tmpt[j1]].y-pot[tmpt[i]].y>=d/2) break; 61 double d3=dis(tmpt[i],tmpt[j])+dis(tmpt[i],tmpt[j1])+dis(tmpt[j1],tmpt[j]); 62 d=min(d,d3); 63 } 64 } 65 } 66 return d; 67 } 68 int main() 69 { 70 // freopen("copy.in","r",stdin); 71 // freopen("copy.out","w",stdout); 72 n=scan(); 73 FOR(i,1,n) 74 { 75 scanf("%lf%lf",&pot[i].x,&pot[i].y); 76 } 77 sort(pot+1,pot+n+1,cmp); 78 double h=par(1,n); 79 printf("%.6lf",h);//求1~n的最近點對 80 return 0; 81 }
View Code

傻逼數學題(math)