zoukankan      html  css  js  c++  java
  • HDU 1589 Stars Couple(计算几何求二维平面的最近点对和最远点对)

    Time Limit: 1000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 930    Accepted Submission(s): 200

    Problem Description

    Can you believe it? After Gardon had solved the problem, Angel accepted him! They were sitting on the lawn, watching the stars. 
    "I still can't believe this!" Gardon said.
    Angel smiled and said: "The reason why I love you does not rest on of who you are, but on who I am when I am with you."
    Gardon answered :"In my view, it's not because I'm lonely and it's not because it's the Valentine's Day. It's because when you realize you want to spend the rest of your life with somebody, you want the rest of your life to start as soon as possible!"
    "Watch the stars! How beautiful!"
    "Just like your eyes!" Gardon replied.
    Angel smiled again:" Did you hear about this: one star means one person. When two people fall in love, their stars will be always nearby."
    "So we are the nearest couple?"
    Now there is the question. Can you point out which couple of stars is nearest? Besides, can you fingle out which couple are most distant?

    Input

    Input contains serveral test cases. Each cases starts with a integer N (2<=N<=50,000). Then N lines follow. Each line have two integers Xi and Yi(-10^9<Xi,Yi<10^9), which show the position of one star.
    The input will be ended with a integer 0.

    Output

    For each case, print the distance of the nearest couple and the most distant couple. 
    Print a blank line after each case.

    Sample Input

    3

    1 1

    0 0

    0 1

    0

    Sample Output

    Case 1:

    Distance of the nearest couple is 1.000

    Distance of the most distant couple is 1.414

    //by zyy 

     

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    using namespace std;
    const int M=50005;
    typedef struct Point
    {
    double x;
    double y;
    }Point;
    Point p[M];
    Point pp[M];
    bool bo[M];
    int stack[M];//form 1 to t;
    double dis(Point A,Point B)
    {
    return sqrt((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y));
    }
    bool cmp(Point a,Point b)
    {
    if(a.x<b.x)
        return true;
    if(a.x>b.x)
        return false;
    if(a.y<b.y)
        return true;
    return false;
    }
    double Xdet(Point A,Point B,Point C)
    {
    double x1,x2,y1,y2;
    x1=B.x-A.x;
    y1=B.y-A.y;
    x2=C.x-A.x;
    y2=C.y-A.y;
    return x1*y2-x2*y1;//大于0在左手边,逆时针
    }
    //把点集凸包化Gram_Scan算法(使用水平序)
    void Gram_Scan(Point *p,int &n)//p从1-n,把点集土包化
    {
    int i,t;
    sort(p+1,p+1+n,cmp);
    for(t=0,i=1;i<=n;i++)
    {
        if(i>1&&p[i].x==p[i-1].x&&p[i].y==p[i-1].y)
          continue;
        p[++t]=p[i];
    }
    n=t;
    t=0;
    memset(bo+1,true,n*sizeof(bo[0]));
    if(n>0)
    {
        stack[++t]=1;
        bo[stack[t]]=false;
    }
    if(n>1)
    {
        stack[++t]=2;
        bo[stack[t]]=false;
    }
    if(n>2)
    {
        for(i=3;i<n;i++)
          if(bo[i]&&Xdet(p[stack[t-1]],p[stack[t]],p[i])>=0)
          {
            stack[++t]=i;
            bo[i]=false;
          }
          else
          {
            while(t>=2&&Xdet(p[stack[t-1]],p[stack[t]],p[i])<0)
            {
              bo[stack[t]]=true;
              t--;
            }
            stack[++t]=i;
            bo[stack[t]]=false;
          }
       for(i=n;i>=1;i--)
         if(bo[i]&&Xdet(p[stack[t-1]],p[stack[t]],p[i])>=0)
         {
           stack[++t]=i;
           bo[i]=false;
         }
         else
         {
           while(t>=2&&Xdet(p[stack[t-1]],p[stack[t]],p[i])<0)
           {
             bo[stack[t]]=true;
             t--;
           }
           stack[++t]=i;
           bo[stack[t]]=false;
         }
         t--;
    }
    for(i=1;i<=t;i++)
        pp[i]=p[stack[i]];
    memcpy(p+1,pp+1,t*sizeof(Point));
    n=t;
    }
    int n,o[M],on;
    int dcmp(double a,double b)
    {
        if(a-b<1e-10&&b-a<1e-10)
            return 0;
        if(a>b)
            return 1;
        return -1;
    }
    bool cmp1(const Point &a,Point &b)
    {
        return dcmp(a.x,b.x)<0;
    }
    bool cmp2(const int&a,const int&b)
    {
        return dcmp(p[a].y,p[b].y)<0;
    }
    double min(double a,double b)
    {
        return a<b?a:b;
    }
    double search(int s,int t)
    {
        int mid=(s+t)/2,i,j;
        double ret=1e300;
        if(s>=t)
            return ret;
        for(i=mid;i>=s&&!dcmp(p[i].x,p[mid].x);i--);ret=search(s,i);
        for(i=mid;i<=t&&!dcmp(p[i].x,p[mid].x);i++);ret=min(ret,search(i,t));on=0;
        for(i=mid;i>=s&&dcmp(p[mid].x-p[i].x,ret)<=0;i--)o[++on]=i;
        for(i=mid+1;i<=t&&dcmp(p[i].x-p[mid].x,ret)<=0;i++)o[++on]=i;
        sort(o+1,o+on+1,cmp2);
        for(i=1;i<=on;i++)
            for(j=1;j<=10;j++)
                if(i+j<=on)
                    ret=min(ret,dis(p[o[i]],p[o[i+j]]));
        return ret;
    }
    int main()
    {
        int n,i,count=0,j;
        double shortdis,longdis;
        while(scanf("%d",&n),n)
        {
            for(i=1;i<=n;i++)
                scanf("%lf%lf",&p[i].x,&p[i].y);
            sort(p+1,p+n+1,cmp1);
            shortdis=search(1,n);
            longdis=0;
            Gram_Scan(p,n);
            for(i=1;i<=n-1;i++)
                for(j=i+1;j<=n;j++)
                    if(dis(p[i],p[j])>longdis)
                        longdis=dis(p[i],p[j]);
            printf("Case %d:
    ",++count);
            printf("Distance of the nearest couple is %.3lf
    ",shortdis);
            printf("Distance of the most distant couple is %.3lf
    
    ",longdis);
        }
        return 0;
    }

     

     

  • 相关阅读:
    查看SQL Server被锁的表以及如何解锁【转】
    JQUERY的$(function(){})和window.onload=function(){}的区别【转】
    安装和使用Redis【转】
    RabbitMQ的简单应用【转】
    Redis集群的搭建【转】
    Spring--如何解决循环依赖
    分布式事务--2PC(两阶段提交)
    CAP理论
    JVM垃圾回收机制
    Redis面试题
  • 原文地址:https://www.cnblogs.com/Annetree/p/6291758.html
Copyright © 2011-2022 走看看