码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1589 Stars Couple(计算几何求二维平面的最近点对和最远点对)

时间:2017-01-17 09:36:51      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:rip   scan   div   because   计算   水平   sid   space   clu   

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:\n",++count);
        printf("Distance of the nearest couple is %.3lf\n",shortdis);
        printf("Distance of the most distant couple is %.3lf\n\n",longdis);
    }
    return 0;
}

 

 

 

HDU 1589 Stars Couple(计算几何求二维平面的最近点对和最远点对)

标签:rip   scan   div   because   计算   水平   sid   space   clu   

原文地址:http://www.cnblogs.com/Annetree/p/6291758.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!