编程之美-2.11 扩展 寻找距离最远的两个点

一、问题描述

    平面上有n个点,如何寻找距离最远的两个点?

二、解题思路

    第一步,寻找凸包(因为最远距离的两个点一定在凸包上)

    第二步,用旋转卡(qia)壳 寻找距离最大的点

    凸包和旋转卡壳算法参见http://blog.csdn.net/kaytowin/article/details/5140111

三、代码实现

#include<iostream>

#include<vector>

#include<algorithm>

#include<cmath>

#include<stack>

#define INF 100000000

using namespace std;



struct point{

    int x;

    int y;

    point(int x1,int y1):x(x1),y(y1){}

    point(){}

};

struct maxLS{

    point p1;

    point p2;

    int dist;

    maxLS(point pp1,point pp2,int dist1):p1(pp1),p2(pp2),dist(dist1){}

    maxLS(){}

};

int xmult(point p1,point p2,point p0){

    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);

}

point p0(INF,INF);

vector<point> points;

vector<point> pstack;

void sort(vector<point>& points1){

    for(int j=points.size()-1;j>=1;j--){

        for(int i=1;i<j;i++){

            int xm=xmult(points[i],points[i+1],p0);



            if(xm<0){

                point tmp=points[i];

                points[i]=points[i+1];

                points[i+1]=tmp;

            }

        }

    }

}

void printPoints(vector<point> ps){

    for(int i=0;i<ps.size();i++){

        cout<<"<"<<ps[i].x<<","<<ps[i].y<<">"<<endl;

    }

}

void convexHull(){

    cout<<"打印输入点集:"<<endl;

    printPoints(points);

    sort(points);

    cout<<"打印按极角排序的点集:"<<endl;

    printPoints(points);

    pstack.push_back(points[0]);

    pstack.push_back(points[1]);

    int stack_top=pstack.size()-1;

    for(int i=2;i<points.size();i++){

        stack_top=pstack.size()-1;

        point pt2=pstack[stack_top];

        point pt1=pstack[stack_top-1];

        point ptcur=points[i];

        int xm=(pt2.x-pt1.x)*(ptcur.y-pt2.y)-(ptcur.x-pt2.x)*(pt2.y-pt1.y);

        while(xm<0){

            

            pstack.pop_back();

            stack_top=pstack.size()-1;

            pt2=pstack[stack_top];

            pt1=pstack[stack_top-1];

            xm=(pt2.x-pt1.x)*(ptcur.y-pt2.y)-(ptcur.x-pt2.x)*(pt2.y-pt1.y);

        

        }

        pstack.push_back(points[i]);

    }

    cout<<"打印凸包点集:"<<endl;

    printPoints(pstack);

}

int dist(point p1,point p2){

    return (p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y);

}

maxLS rotatingCalipers(){

    int q=1;

    int maxLength=0;

    maxLS mls;

    for(int i=0;i<pstack.size()-1;i++){

        while(xmult(pstack[i+1],pstack[(q+1)%pstack.size()],pstack[i])>xmult(pstack[i+1],pstack[q],pstack[i])){

            q=(q+1)%pstack.size();

        }

        int d1=dist(pstack[i],pstack[q]);

        int d2=dist(pstack[i+1],pstack[q]);

        if(d1>d2){

            maxLength=d1;

            mls=maxLS(pstack[i],pstack[q],d1);



        }else{

            maxLength=d2;

            mls=maxLS(pstack[i+1],pstack[q],d2);

        }

        

        

    }

    return mls;

}

int main(){

    cout<<"请输入节点数:"<<endl;

    int n;

    cin>>n;

    cout<<"请输入"<<n<<"个节点:"<<endl;

    int p0i=0;

    int t=0;

    while(n--){

        int x;

        int y;

        cin>>x>>y;

        if(y<p0.y||(y==p0.y&&x<p0.x)){

            p0.x=x;

            p0.y=y;

            p0i=t;

            

        }

        t++;

        points.push_back(point(x,y));

    }

    point tmp=points[0];

    points[0]=points[p0i];

    points[p0i]=tmp;



    convexHull();

    maxLS maxL= rotatingCalipers();

    cout<<"两点最大距离:"<<maxL.dist<<endl;

    cout<<"两点分别是:"<<"<"<<maxL.p1.x<<","<<maxL.p1.y<<">,";

    cout<<"<"<<maxL.p2.x<<","<<maxL.p2.y<<">"<<endl;

    system("pause");

    return 0;

}

四、输入:

9

3 1
4 3
5 2
3 5
6 5
8 4
5 7
2 6
1 4

五、输出:

编程之美-2.11 扩展 寻找距离最远的两个点

 

你可能感兴趣的:(编程之美)