tjut 1007

来源:互联网 发布:淘宝烟标搜不到了 编辑:程序博客网 时间:2024/06/09 23:34
#include<iostream>  #include<cmath>  #include<algorithm>  #include<iomanip>  using namespace std;    #define max 100005//100000    struct Point  {      double x;      double y;  };    Point * p= new Point[max];  //p = new Point[max];    double Min(double a,double b)  {      if(a<b)          return a;      else          return b;  }    //Point p[max];  class ClosetPoint  {    private:         //保存点         int num;    public:         void Input(int iCount);//传进一个要输入的顶点数目iCount        // bool cmp_x(const Point& a,const Point& b);//比较排序        // bool cmp_y(Point a,Point b);         double Seprate(int start,int end);//分治         double Merge(double curmin,int start,int end);         double Distance(Point* a,Point*b);  };    int /*ClosetPoint::*/cmp_x(const void * a, const void  *b)  {      /*if(((Point*)a)->x!=((Point*)b)->x)//被注释掉的比较方法有问题?????哥哥10000个问号啊cmp_y也如此         return ((Point*)a)->x<((Point*)b)->x;     else         return ((Point*)a)->y<((Point*)b)->y;*/      double temp = ((Point*)a)->x-((Point*)b)->x;      if(temp>0)          return 1;      else if(temp<0)          return -1;      else          return 0;           }    int /*ClosetPoint::*/cmp_y(const void *a,const void * b)  {  /*  if(((Point*)a)->y!=((Point*)b)->y)         return ((Point*)a)->y<((Point*)b)->y;     else         return ((Point*)a)->x<((Point*)b)->x;*/      double  temp = ((Point*)a)->y-((Point*)b)->y;      if(temp>0)          return 1;      else if(temp==0)          return 0;      else          return -1;  }    void ClosetPoint::Input(int iCount)//接受输入的顶点信息  {         num =iCount;     for(int i =0;i<iCount;i++)         cin>>p[i].x>>p[i].y;      qsort(p,num,sizeof(p[0]),cmp_x);//先X轴排序  }    double ClosetPoint::Distance(Point* a,Point* b)  {      return sqrt((b->x-a->x)*(b->x-a->x)+(b->y-a->y)*(b->y-a->y));//注意最外面的括号不要忘记加  }    double ClosetPoint::Seprate(int start,int end)//分治的起始位置  {      if(end-start==1)//只有两个顶点时候          return Distance(&p[start],&p[end]);      else if(end-start==2)//只有三个顶点时候,直接枚举咯,小数目      {          double temp1=Distance(&p[start],&p[start+1]);          double temp2=Distance(&p[start],&p[end]);          double temp3=Distance(&p[start+1],&p[end]);          double temp= Min(temp1,temp2);         return Min(temp,temp3);      }        int mid =(start+end)/2;      double dlm=Seprate(start,mid);      double drm=Seprate(mid+1,end);      double curmin = Min(dlm,drm);//这里当时谢了个Max函数,ZOJ居然AC了            return Merge(curmin,start,end);  }  Point Yp[max];  double ClosetPoint::Merge(double curmin,int start,int end)  {    int mid = (start+end)/2;    int j=0;    for(int s=start;s<=end;s++)    {        if((p[s].x>p[mid].x-curmin)&&(p[s].x<p[mid].x+curmin))//在中间那个垂直区域的顶点才吸收进Yp        {            Yp[j].x=p[s].x;            Yp[j++].y=p[s].y;        }    }     qsort(Yp,j,sizeof(Yp[0]),cmp_y);//对这些吸收进来Yp的元素,进行升序排列      for(int i=0;i<j;i++)    {        for(int k=i+1;k<=i+7&&k<j;k++)//检测枚举顶点后的七个顶点--,据说数据很弱,枚举三个既可以,笔者试了一下,为嘛我的不行呢?嘿嘿        {            double dis = Distance(&Yp[i],&Yp[k]);            if(dis<curmin)//更新curmin            {                curmin = dis;            }        }    }      return curmin;  }    int main()  {           int iCount;      while(cin>>iCount)      {                              if(iCount==0)          break;      ClosetPoint cp;      cp.Input(iCount);      double curmin = cp.Seprate(0,iCount-1);      double min = cp.Merge(curmin,0,iCount-1);     // cout<<fixed<<setprecision(2)<<min<<endl;      cout.precision(2);  //  cout.setf(ios::fixed);      cout.setf(ios::showpoint);      cout<<min/2.0<<endl;      }  /*  Point p1,p2;     p1.x=0;     p1.y=0;     p2.x=1;     p2.y=1;     cout<<cp.Distance(p1,p2)<<endl; //test Distance method*/      return 0;  }  

0 0
原创粉丝点击