(nlogn)的时间复杂度求 最近点对 hdu 1007 凹凸曼与小怪兽的故事 poj3714 Raid
hdu 1007 Quoit Design
http://acm.hdu.edu.cn/showproblem.php?pid=1007
zoj 2107 Quoit Design
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2107
【题意 】半天没搞懂 题目在讲什么 百度的题意 意思就是 输出最近点对的距离的一般
参考算法讲解
ac代码
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<math.h> 6 using namespace std; 7 struct node{double x;double y;}p[100002]; 8 int temp[100002]; 9 10 int cmp(node a,node b) 11 { 12 if(a.x==b.x) 13 return a.y<b.y; 14 return a.x<b.x; 15 } 16 17 int cmp1(int i,int j) 18 { 19 return p[i].y<p[j].y; 20 } 21 22 double dis(int i,int j) 23 { 24 double q; 25 q=sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y)); 26 return q; 27 } 28 29 double find1(int left,int right) 30 { 31 int k,i,j; 32 if(right-left==1) 33 return dis(left,right); 34 if(right<=left) 35 return 10000000; 36 int m; 37 m=(left+right)/2; 38 double d; 39 d=min(find1(left,m),find1(m+1,right)); 40 41 for(k=0,i=left;i<=right;i++) //把m这条垂线的左边d部分 和右边d部分 42 if(fabs(p[i].x-p[m].x)<=d) 43 temp[k++]=i; // temp数组存放的是序号 44 45 sort(temp,temp+k,cmp1); 46 for(i=0;i<k;i++) 47 for(j=i+1;j<k&&p[temp[j]].y-p[temp[i]].y<d;j++) 48 { 49 double dd=dis(temp[i],temp[j]); 50 if(dd<d) 51 d=dd; 52 } 53 return d; 54 } 55 56 int main() 57 { 58 int i,j,n,m,t; 59 while(scanf("%d",&n),n) 60 { 61 for(i=0;i<n;i++) 62 scanf("%lf%lf",&p[i].x,&p[i].y); 63 sort(p,p+n,cmp); 64 printf("%.2lf\n",find1(0,n-1)/(double)2); 65 } 66 return 0; 67 }
poj 3714 Raid
http://poj.org/problem?id=3714
【题意】 求两集合的最近点对
【思路】只要把同一集合里的两点的距离 赋为无穷大 就和前面一样了
注意 里面有几个要排序的地方 要是结构体排序会比较耗时 之前没有注意这一点超时了好久
解决的办法是 用数组记录下标 排序时只要排这个数组就行 具体看代码
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<math.h> using namespace std; #define INF 2000000000 double x[200002],y[200002]; int temp[200002],index[200002],n; int cmp(int i,int j) { if(x[i]==x[j]) return y[i]<y[j]; return x[i]<x[j]; } int cmp1(int i,int j) { return y[i]<y[j]; } double dis(int i,int j) { if(i<n&&j<n) return INF; if(i>=n&&j>=n) return INF; return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); } double min1(double a,double b,double c) { return min(min(a,b),c); } double find1(int left,int right) { int i,j,k; if(left>=right) return INF; if(left+1==right) return dis(index[left],index[right]); if(left+2==right) return min1(dis(index[left],index[left+1]),dis(index[left+1],index[right]),dis(index[left],index[right])); int m; m=(left+right)/2; double d; d=min(find1(left,m),find1(m+1,right)); for(i=left,k=0;i<=right;i++) if(fabs(x[index[i]]-x[index[m]])<d) temp[k++]=index[i]; sort(temp,temp+k,cmp1); for(i=0;i<k;i++) for(j=i+1;j<k&&y[temp[j]]-y[temp[i]]<d;j++) { double dd=dis(temp[i],temp[j]); if(dd<d) d=dd; } return d; } int main() { int i,j,m,t,a,b; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i<n*2;i++) { scanf("%lf%lf",&x[i],&y[i]); index[i]=temp[i]=i; } sort(index,index+n*2,cmp); printf("%.3lf\n",find1(0,n*2-1)); } return 0; }
中南oj 凹凸曼和小怪兽的故事
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1309
【题意】 和上题一样再除以个(a+b)就行了
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 7 using namespace std; 8 #define INF 2000000000 9 double x[200002],y[200002]; 10 11 int temp[200002],index[200002],n; 12 13 int cmp(int i,int j) 14 { 15 if(x[i]==x[j]) 16 return y[i]<y[j]; 17 return x[i]<x[j]; 18 } 19 20 int cmp1(int i,int j) 21 { 22 return y[i]<y[j]; 23 } 24 25 double dis(int i,int j) 26 { 27 if(i<n&&j<n) 28 return INF; 29 if(i>=n&&j>=n) 30 return INF; 31 return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); 32 } 33 34 double min1(double a,double b,double c) 35 { 36 return min(min(a,b),c); 37 } 38 39 double find1(int left,int right) 40 { 41 int i,j,k; 42 if(left>=right) 43 return INF; 44 if(left+1==right) 45 return dis(index[left],index[right]); 46 if(left+2==right) 47 return min1(dis(index[left],index[left+1]),dis(index[left+1],index[right]),dis(index[left],index[right])); 48 int m; 49 m=(left+right)/2; 50 double d; 51 d=min(find1(left,m),find1(m+1,right)); 52 53 for(i=left,k=0;i<=right;i++) 54 if(fabs(x[index[i]]-x[index[m]])<d) 55 temp[k++]=index[i]; 56 57 sort(temp,temp+k,cmp1); 58 for(i=0;i<k;i++) 59 for(j=i+1;j<k&&y[temp[j]]-y[temp[i]]<d;j++) 60 { 61 double dd=dis(temp[i],temp[j]); 62 if(dd<d) 63 d=dd; 64 } 65 return d; 66 } 67 68 int main() 69 { 70 int i,j,m,t,a,b; 71 while(scanf("%d%d%d",&n,&a,&b)!=EOF) 72 { 73 for(i=0;i<n*2;i++) 74 { 75 scanf("%lf%lf",&x[i],&y[i]); 76 index[i]=temp[i]=i; 77 } 78 sort(index,index+n*2,cmp); 79 printf("%.3lf\n",find1(0,n*2-1)/(double)(a+b)); 80 } 81 return 0; 82 }
hdu 4631 Sad Love Story
http://acm.hdu.edu.cn/showproblem.php?pid=4631
【题意】: