zoukankan      html  css  js  c++  java
  • HDU 1007(套圈 最近点对距离)

    题意是求出所给各点中最近点对的距离的一半(背景忽略)。

    用分治的思想,先根据各点的横坐标进行排序,以中间的点为界,分别求出左边点集的最小距离和右边点集的最小距离,然后开始合并,分别求左右点集中各点与中间点的距离,从这些距离与点集中的最小距离比较,求得最小距离,此处可按纵坐标排序,将纵坐标距离已经大于之前最小距离的部分都剪枝。

    代码如下:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int n,a[100009];
     4 struct point
     5 {
     6     double x,y;
     7 }p[100009];
     8 bool cmpx(point a,point b)
     9 {
    10     return a.x < b.x;
    11 }
    12 bool cmpy(int a,int b)
    13 {
    14     return p[a].y < p[b].y;
    15 }
    16 double dis(point a,point b)
    17 {
    18     return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );
    19 }
    20 double min(double a,double b,double c)
    21 {
    22     if(a>b) return b>c?c:b;
    23     return a>c?c:a;
    24 }
    25 double fin(int from,int to)
    26 {
    27     if(from+1 == to ) return dis(p[from],p[to]);
    28     if(from+2 == to ) return min(dis(p[from],p[from+1]),dis(p[from],p[to]),dis(p[from+1],p[to]));
    29     int mid = (from+to)>>1;
    30     double ans = min(fin(from,mid),fin(mid+1,to));
    31     int cnt = 0;
    32     for(int i = from; i <= to; i++)
    33         if(abs(p[i].x-p[mid].x) <= ans) a[cnt++] = i;
    34     sort(a,a+cnt,cmpy);
    35     for(int i = 0; i < cnt; i++)
    36         for(int j = i+1; j < cnt; j++)
    37         {
    38             if(p[a[j]].y-p[a[i]].y >= ans) break;
    39             ans = min(ans,dis(p[a[i]],p[a[j]]));
    40         }
    41     return ans;
    42 }
    43 int main()
    44 {
    45     while(scanf("%d",&n)&&n)
    46     {
    47         for(int i = 0; i < n; i++)
    48             scanf("%lf %lf",&p[i].x,&p[i].y);
    49         sort(p,p+n,cmpx);
    50         printf("%.2lf
    ",fin(0,n-1)/2);
    51     }
    52     return 0;
    53 }
    View Code

    但是呢,开始时本人并不是这么写的,而是求了所有点中最小的横坐标和纵坐标,然后以此为参照点,分别求其他各点到参照点的距离,以距离排序,再求出相邻两点距离的最小值。这么写是上面写法的用时一半左右,尽管 AC 了,但是这么写是不对的......

    如图所示,图中的点 1 和点 2 距离比点 1 和点 3 的距离更近,但是第二种方法则是用点 1 和点 3距离与点 3 和点 2 距离中求较小值。(题目的测试数据中可能没有这样的数据吧......)

    第二种方法的代码如下:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int n;
     4 struct point
     5 {
     6     double x,y,dis;
     7 }st,p[100009];
     8 bool cmp(point a,point b)
     9 {
    10     if(a.dis!=b.dis) return a.dis < b.dis;
    11     return a.x<b.x;
    12 }
    13 double dist(point a,point b)
    14 {
    15     return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );
    16 }
    17 int main()
    18 {
    19     double sml;
    20     while(scanf("%d",&n)&&n)
    21     {
    22         st.x = st.y = 1000000.0;
    23         sml = 1000000.0;
    24         for(int i = 0; i < n; i++)
    25         {
    26             scanf("%lf %lf",&p[i].x,&p[i].y);
    27             if(p[i].x < st.x) st.x = p[i].x;
    28             if(p[i].y < st.y) st.y = p[i].y;
    29         }
    30         for(int i = 0; i < n; i++)
    31             p[i].dis = dist(p[i],st);
    32         sort(p,p+n,cmp);
    33         for(int i = 1; i < n; i++)
    34             if(dist(p[i],p[i-1])<sml) sml = dist(p[i],p[i-1]);
    35         printf("%.2lf
    ",sml/2);
    36     }
    37     return 0;
    38 }
    View Code
    日后若能有更好的想法,再来完善。 希望看到的大神不吝赐教 orz
  • 相关阅读:
    Yield Usage Understanding
    Deadclock on calling async methond
    How to generate file name according to datetime in bat command
    Run Unit API Testing Which Was Distributed To Multiple Test Agents
    druid的关键参数+数据库连接池运行原理
    修改idea打开新窗口的默认配置
    spring boot -thymeleaf-url
    @pathvariable和@RequestParam的区别
    spring boot -thymeleaf-域对象操作
    spring boot -thymeleaf-遍历list和map
  • 原文地址:https://www.cnblogs.com/Taskr212/p/9513210.html
Copyright © 2011-2022 走看看