poj 3608 Bridge Across Islands 凸包最短距离

            题意:求两个凸包的最短距离

            思路:将凸包逆时针化,寻找一个凸包的y最小的一个点,另一个凸包y最大的点,分别按逆时针旋转卡壳,更新最短距离。

            代码:

            

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#define sqr(x) ((x)*(x))
#define maxn 10000+10

using namespace std;
const double eps=1e-8;
const double pi=acos(-1.0);

int dcmp(double x)
{
    if(x<-eps) return -1;
    else return x>eps;
}
struct cpoint
{
    double x,y;
    cpoint(){}
    cpoint (double x,double y) :x(x),y(y){}
    cpoint operator - (const cpoint &u) const {
       return cpoint(x-u.x,y-u.y);
    }
    double operator * (const cpoint &u) const {
       return x*u.y-y*u.x;
    }
    double operator ^ (const cpoint &u) const {
       return x*u.x+y*u.y;
    }
    bool operator == (const cpoint &u) const {
       return dcmp(x-u.x)==0&&dcmp(y-u.y)==0;
    }
};
double cross (cpoint o,cpoint p,cpoint q)
{
    return (p-o)*(q-o);
}
double dot(cpoint o,cpoint p,cpoint q)
{
    return (p-o)^(q-o);
}
double dis(cpoint p,cpoint q)
{
    return sqrt(sqr(p.x-q.x)+sqr(p.y-q.y));
}
double dissqr(cpoint p,cpoint q)
{
    return sqr(p.x-q.x)+sqr(p.y-q.y);
}
double pointtoline(cpoint p0,cpoint p1,cpoint p2,cpoint &cp)
{
    double d=dis(p1,p2);
    double s=cross(p1,p2,p0)/d;
    cp.x=p0.x+s*(p2.y-p1.y)/d;
    cp.y=p0.y-s*(p2.x-p1.x)/d;
    return fabs(s);
}
bool pointonsegment(cpoint p0,cpoint p1,cpoint p2)
{
    return dcmp(cross(p0,p1,p2))==0&&dcmp(dot(p0,p1,p2))<=0;
}
cpoint bp;
double pointtoseg(cpoint p0,cpoint p1,cpoint p2)
{
    cpoint cp;
    double d=pointtoline(p0,p1,p2,cp);
    if(pointonsegment(cp,p1,p2)) return d;
    else return min(dis(p0,p1),dis(p0,p2));
}
double dispallseg(cpoint p0,cpoint p1,cpoint p2,cpoint p3)
{
    return min(min(pointtoseg(p0,p2,p3),pointtoseg(p1,p2,p3)),min(pointtoseg(p2,p0,p1),pointtoseg(p3,p0,p1)));
}
void anticlockwise(cpoint cp[],int n)
{
    for(int i=0;i<n-2;i++)
    {
        double t=cross(cp[i],cp[i+1],cp[i+2]);
        if(dcmp(t)>0) return ;
        if(dcmp(t)<0)
        {
            reverse(cp,cp+n);
            return ;
        }
    }
}
double rotating(cpoint ch1[],int n,cpoint ch2[],int m)
{
    int p=0,q=0;
    for(int i=0;i<n;i++)
      if(dcmp(ch1[i].y-ch1[p].y)<0)
         p=i;
    for(int i=0;i<m;i++)
      if(dcmp(ch2[i].y-ch2[i].y)>0)
         q=i;
    ch1[n]=ch1[0];
    ch2[m]=ch2[0];
    double tmp,res=1e99;
    for(int i=0;i<n;i++)
    {
        while((tmp=cross(ch1[p],ch1[p+1],ch2[q+1])-cross(ch1[p],ch1[p+1],ch2[q]))>eps)
            q=(q+1)%m;
        if(dcmp(tmp)<0)
           res=min(res,pointtoseg(ch2[q],ch1[p],ch1[p+1]));
        else
           res=min(res,dispallseg(ch1[p],ch1[p+1],ch2[q],ch2[q+1]));
           p=(p+1)%n;
    }
    return res;
}
cpoint ch1[maxn],ch2[maxn];
int n,m;
double solve()
{
    anticlockwise(ch1,n);
    anticlockwise(ch2,m);
    return min(rotating(ch1,n,ch2,m),rotating(ch2,m,ch1,n));
}
int main()
{
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        if(n==0&&m==0) break;
        for(int i=0;i<n;i++)
          scanf("%lf %lf",&ch1[i].x,&ch1[i].y);
        for(int i=0;i<m;i++)
          scanf("%lf %lf",&ch2[i].x,&ch2[i].y);
        printf("%.5lf\n",solve());
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单片微型计算机(MCU)经过多年的发展,在性能上有很大的进步,在型号上发展到上千种类,已经广泛应用于人类社会生活的各个领域。单片机课程已经成为高校计算机、自动化、测控以及电子信息工程等专业的重要课程。该课程是一门理论性和实践性都很强的课程,在实际教学中,应将理论教学和实验教学紧密结合。学生在掌握理论知识之余,必须通过编写程序、设计硬件电路、仿真、调试这一系列的实验过程,才能更好地掌握单片机的结构原理和应用技能。随着单片机及其接口技术的飞速发展,目前市场上供应的编程仿真实验资源并不能完全满足高校单片机课程教与学的需求,构建低成本、技术先进、源码公开的单片机编程仿真实验系统,对我国单片机课程的教学和单片机领域人才的培养具有重要的现实意义。 本论文结合目前教学中对单片机编程仿真实验系统的实际需求,采用模块化结构设计思想,精心设计和开发了单片机编程仿真实验系统。该单片机编程仿真实验系统由PC机端单片机编程控制软件和单片机编程仿真实验板两部分组成。PC机端的单片机编程控制软件可以自动检测到连接到单片机编程仿真实验板上的单片机,控制单片机编程器擦除、写入、读出、校验目标单片机ROM中的程序,以十六进制文件(.HEX文件)格式显示在控制界面内;单片机仿真实验系统能够把写入单片机的程序实时地运行,并呈现实际运行效果。单片机编程控制软件和单片机仿真实验板组成一个完整的单片机编程仿真实验系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值