zoukankan      html  css  js  c++  java
  • (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
    ",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
    ",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
    ",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

    【题意】:

  • 相关阅读:
    eslint 入门项目搭建过程
    ES6 模块化笔记
    闭包
    JavaScript 内存相关知识
    Mac 配置Charles,抓取移动设备数据
    jquery.cookie的path坑
    如何模拟click事件,打开一个a标签链接?
    6月份开发问题整理
    js 淡入淡出的tab选项卡
    点击弹出模态框-以登录表单为例
  • 原文地址:https://www.cnblogs.com/assult/p/3506026.html
Copyright © 2011-2022 走看看