(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;
}
View Code

  

中南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 }
View Code

 

hdu 4631 Sad Love Story

http://acm.hdu.edu.cn/showproblem.php?pid=4631

【题意】:

 

 

 

 

posted @ 2014-01-05 16:49  galaxy77  阅读(258)  评论(0编辑  收藏  举报