zoukankan      html  css  js  c++  java
  • 算法分析第五次作业

    1. 问题

      在包含有n个点的集合S中,找出距离最近的两个点。设 p1(x1,y1),p2(x2,y2),……,pn(xn,yn)是平面的n个点。 严格地将,最近点对可能不止一对,此例输出一对即可。

    2. 解析

      我们先根据x坐标排序,进行递归算出每一部分的距离,在根据y坐标排序计算每一部分之间的最近距离,最后得到答案。

    同时我们在进行第二部分计算的时候,通过鸽舍原理易知,最多需要计算距离中心点y坐标最近的6个点来得到答案。

    3. 设计

        在利用分治法思想解决此问题时,首先考虑将最近对问题进行分治,设计其分治策略。将集合S分成两个子集S1和S2,根据平衡子问题原则,每个子集中的点数大致都为n/2。这样分治后,最近点对将会出现三种情况:在S1中,在S2中或者最近点对分别在集合S1和S2中。利用递归分析法分别计算前两种情况,第三种方法另外分析。求解出三类子情况后,再合并三类情况,比较分析后输出三者中最小的距离。

    4. 分析

     

     

    5. 源码

    https://github.com/Tinkerllt/algorithm-work.git

      1 #include <iostream>
      2 #include <string>
      3 #include <vector>
      4 #include <algorithm>
      5 #include <cmath>
      6 #include <cstdlib>
      7 #include <ctime>
      8 #include <iomanip>
      9 using namespace std;
     10 const int maxn = 0x3f3f3f3f;
     11 struct Point
     12 {
     13     int x,y;
     14     friend ostream & operator << (ostream & out,const Point& p);
     15     Point(int _x=0,int _y=0):x(_x),y(_y){}
     16     bool operator < (const Point& rhs)const{
     17         return x < rhs.x;
     18     }
     19 };
     20 ostream & operator << (ostream & out,const Point& p){
     21     out<<"("<<setw(2)<<p.x<<","<<setw(2)<<p.y<<")";
     22     return out;
     23 }
     24 bool cmp(const Point&a,const Point&b) //按x坐标排序
     25 {
     26     return a.x<b.x;
     27 }
     28 bool cmp2(const Point&a,const Point&b) //按y坐标排序
     29 {
     30     return a.y<b.y;
     31 }
     32 
     33 double Dis(Point a,Point b)
     34 {
     35     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
     36 }
     37 double min(double a,double b,double c)
     38 {
     39     return min(min(a,b),c));  
     40 }
     41 
     42 double ClosestPoint(vector<Point> points,int m,int n)  //左闭右开
     43 {
     44     if(n-m<2) return maxn;
     45     if(n-m==2)
     46     {
     47         return Dis(points[m],points[n-1]);
     48     }
     49     if(n-m==3)
     50     {
     51         double a = Dis(points[m],points[n-1]);
     52         double b = Dis(points[m],points[n-2]);
     53         double c = Dis(points[n-1],points[n-2]);
     54         return min(a,b,c);
     55     }
     56     int mid = (m+n)/2;
     57     int mm = points[mid].x;
     58 
     59     double d1 = ClosestPoint(points,m,mid); // 左边区域最短距离
     60     double d2 = ClosestPoint(points,mid,n);  // 右边区域最短距离
     61     double minn = min(d1,d2);
     62     vector<Point> left,right;
     63     for(int i=m;i<mid;++i)
     64     {
     65         if(points[i].x>mm-minn)
     66             left.push_back(points[i]);
     67     }
     68     for(int i=mid;i<n;++i)
     69     {
     70         if(points[i].x<=mm+minn)
     71             right.push_back(points[i]);
     72     }
     73     sort(right.begin(),right.end(),cmp2); //按y坐标排序
     74     double mindist = 100000;
     75     for(int i=0;i<(int)left.size();i++)   //遍历左边所有点求与右边最短距离
     76     {
     77         for(int j=0;j<(int)right.size();j++)
     78         {
     79             if(abs(left[i].y-right[j].y)<minn)
     80             {
     81                 double d = Dis(left[i],right[j]);
     82                 if(d<min) mindist = d;
     83             }
     84         }
     85     }
     86     return min(minn,mindist);
     87 }
     88 int main()
     89 {
     90     //freopen("out.txt","w",stdout);
     91     vector<Point> points;
     92     srand(time(NULL));
     93     int n = 15;
     94     for(int i=0;i<n;i++)
     95     {
     96         Point point;
     97         point.x = rand()%71;
     98         point.y = rand()%61;
     99     //    cin>>point.x>>point.y;
    100         points.push_back(point);
    101     }
    102     sort(points.begin(),points.end(),cmp);
    103     for(int i=0;i<n;i++)
    104     {
    105         //cout << points[i].x <<" "<< points[i].y <<endl;
    106         cout<<points[i]<<endl;
    107     }
    108     cout << "分治法求得的答案为:"<< ClosestPoint(points,0,points.size()) << endl ;
    109     return 0;
    110 }
    View Code
  • 相关阅读:
    Transition 过渡/转场动画(一)
    动态创建类/ swizzle class
    Protocol协议分发器
    UITableView 支持左右滑动(二)
    UITableView 支持左右滑动(一)
    CATiledLayer显示超大图片的解决方案
    ReplicatorLayer 复制图层
    iOS OpenGL ES简单绘制纹理
    iOS OpenGL ES简单绘制三角形
    Mac定时执行脚本_服务launchctl
  • 原文地址:https://www.cnblogs.com/tinkerx/p/12604901.html
Copyright © 2011-2022 走看看