hdu1007最小点对

讲解网上都有。

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define maxn 100002
struct ss
{
    double x;
    double y;
};
ss px[maxn],py[maxn];
bool cmpx(ss p1,ss p2)
{
    return p1.x<p2.x;
}
bool cmpy(ss p1,ss p2)
{
    return p1.y<p2.y;
}
double get_dis(ss p1,ss p2)
{
    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
double mindis(double a,double b)
{
    return a>b?b:a;
}
double closest(int s,int e)
{
    if(e-s==1)
      return get_dis(px[s],px[e]);
    if(e-s==2)
      return mindis(get_dis(px[s],px[s+1]),mindis(get_dis(px[s],px[e]),get_dis(px[s+1],px[e])));
    int mid=(s+e)>>1;
    double ans=mindis(closest(s,mid),closest(mid+1,e));
    int i,j,cnt=0;
    for(i=s;i<=e;i++)
       if(px[i].x>=px[mid].x-ans&&px[i].x<=px[mid].x+ans)
         py[cnt++]=px[i];
    std::sort(py,py+cnt,cmpy);
    for(i=0;i<cnt;i++)
      for(j=i+1;j<cnt;j++)
      {
          if(py[j].y-py[i].y>=ans)
           break;
          ans=mindis(ans,get_dis(py[i],py[j]));
      }
    return ans;
}
int main()
{
    //freopen("Input.txt","r",stdin);
    int n,i;
    while(scanf("%d",&n)&&n)
    {
        for(i=0;i<n;i++)
         scanf("%lf%lf",&px[i].x,&px[i].y);
        std::sort(px,px+n,cmpx);
        double dis=closest(0,n-1);
        printf("%.2lf\n",dis/2);
    }
    return 0;
}

poj 3714 

多加了已给判断,并且是另一种求最小点对的方法。当成模板用。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const double inf=1e9;
struct node
{
    double x,y;
    int id;
}point[200005];
int n;
bool cmp(node p1,node p2)
{
    if(p1.x != p2.x) return p1.x < p2.x;
    else return p1.y < p2.y;
}
double dist(node a, node b)
{
    if(a.id==b.id) return inf;
    return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
}
double getmin(double a, double b)
{
    return a<b?a:b;
}
double Get_Small_Dis(int l,int r)
{
    if(l == r)
        return inf;
    if(l == r - 1) //两个点
        return dist(point[l],point[r]);
    if(l == r - 2)
        return getmin(getmin(dist(point[l],point[l+1]),dist(point[l+1],point[l+2])),dist(point[l],point[l+2]));
    int i,j,mid = (l+r) >> 1;
    double res = getmin(Get_Small_Dis(l,mid),Get_Small_Dis(mid+1,r));
    for(i=l;i<=r;i++)
    {
         for(j=i+1;j<=i+5 && j<=r;j++)
         {
             res = getmin(res,dist(point[i],point[j]));
         }
    }
    return res;
}
void init(double &res) //输入函数,节约时间,poj上排名靠前,运行时间不超过300ms,个人猜也是用输入外挂了吧。
{
    char ch;
    int flag=0,tmp=0,n,m,num=0;
    while((ch=getchar())<'0'||ch>'9')
       if(ch=='-') flag=1;
    for(m=0,n=0; (ch>='0'&&ch<='9')|| (ch=='.');ch=getchar())
    {
         if(ch=='.') { tmp=1;continue;}
         if(!tmp) m=m*10+ch-'0';
         if(tmp) { n=n*10+ch-'0'; num++;}
    }
    res=m+n*1.0/pow(10,num);
    if(flag) res*=-1;
}
int main()
{
    //freopen("Input.txt","r",stdin);
    int i,ncase;
    scanf("%d",&ncase);
    while(ncase--)
    {
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
             init(point[i].x);
             init(point[i].y);
             point[i].id=0;
        }
        n<<=1;
        for(;i<n;i++)
        {
            init(point[i].x);
            init(point[i].y);
            point[i].id=1;
        }
        sort(point,point+n,cmp);
        double ans = Get_Small_Dis(0,n-1);
        printf("%.3f\n",ans);
    }
    return 0;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值