傻逼数学题
题目描述
由于乱码,复制不下来,只好截图了
输入格式
第一行一个正整数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 }