POJ 3608

1.计算P上y坐标值最小的顶点(称为 yminP )和Q上y坐标值最大的顶点(称为 ymaxQ)。

2.为多边形在 yminP 和 ymaxQ 处构造两条切线 LP 和 LQ 使得他们对应的多边形位于他们的右侧。

  此时 LP 和 LQ 拥有不同的方向, 并且 yminP 和 ymaxQ 成为了多边形间的一个对踵点对。

3.计算距离(yminP,ymaxQ) 并且将其维护为当前最小值。

4.顺时针同时旋转平行线直到其中一个与其所在的多边形的边重合。

5.如果只有一条线与边重合, 那么只需要计算“顶点-边”对踵点对和“顶点-顶点”对踵点对距离。 都将他们与当前最小值

比较, 如果小于当前最小值则进行替换更新。如果两条切线都与边重合,那么情况就更加复杂了。如果边“交叠”,也就是

可以构造一条与两条边都相交的公垂线(但不是在顶点处相交), 那么就计算“边-边”距离。 否则计算三个新的“顶点-顶

点”对踵点对距离。 所有的这些距离都与当前最小值进行比较, 若小于当前最小值则更新替换。

6.重复执行步骤4和步骤5, 直到新的点对为(yminP,ymaxQ)。

7.输出最小距离

 

这是求两凸包最短距离的经典算法。但是,不知为什么,我的代码死活过不了。。。T_T

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <cmath>
  6 using namespace std;
  7 const double eps=0.00000001;
  8 
  9 struct point {
 10     double x,y;
 11 }p[10050],q[10050];
 12 int n,m;
 13 int ansp[10050],ansq[10050],cntp,cntq;
 14 int st[10050],stop;
 15 
 16 bool cmp(point A,point B){
 17     if(A.y<B.y) return true;
 18     else if(A.y==B.y){
 19         if(A.x<B.x) return true;
 20     }
 21     return false;
 22 }
 23 
 24 double dist(point a , point b){
 25     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
 26 }
 27 
 28 double multi(point a, point b, point c){
 29     point p1; p1.x=a.x-c.x; p1.y=a.y-c.y;
 30     point p2; p2.x=b.x-c.x; p2.y=b.y-c.y;
 31     return (p1.x*p2.y-p1.y*p2.x);
 32 }
 33 
 34 void forTU(point *pot, int &allVex, int *anp, int &cnt){
 35 //    cout<<allVex<<"all"<<endl;
 36     stop=cnt=0;
 37     st[stop++]=0; st[stop++]=1;
 38     for(int i=2;i<allVex;i++){
 39         while(stop>1&&multi(pot[i],pot[st[stop-1]],pot[st[stop-2]])<=0) stop--;
 40         st[stop++]=i;
 41     }
 42     for(int i=0;i<stop;i++)
 43     anp[cnt++]=st[i];
 44     stop=0;
 45     st[stop++]=allVex-1; st[stop++]=allVex-2;
 46     for(int i=allVex-3;i>=0;i--){
 47         while(stop>1&&multi(pot[i],pot[st[stop-1]],pot[st[stop-2]])<=0) stop--;
 48         st[stop++]=i;
 49     }
 50     for(int i=1;i<stop;i++)
 51     anp[cnt++]=st[i];
 52 //    for(int i=0;i<cnt;i++)
 53 //    cout<<anp[i]<<endl;
 54 //    cout<<endl;
 55 }
 56 
 57 double dotcross(point a,point b, point c){
 58     point p1; p1.x=a.x-c.x; p1.y=a.y-c.y;
 59     point p2; p2.x=b.x-c.x; p2.y=b.y-c.y;
 60     return p1.x*p2.x+p1.y*p2.y;
 61 }
 62 
 63 double pline(point a,point b,point c){
 64     return (fabs(multi(a,b,c)))/(dist(a,b));
 65 }
 66 
 67 double pseg(point a,point b,point c){
 68     if(dotcross(a,c,b)<-eps) return dist(b,c);
 69     if(dotcross(b,c,a)<-eps) return dist(a,c);
 70     return pline(a,b,c);
 71 }
 72 
 73 double paral(point a1,point a2, point b1,point b2 ){
 74     double ans1=min(pseg(a1,a2,b1),pseg(a1,a2,b2));
 75     double ans2=min(pseg(b1,b2,a1),pseg(b1,b2,a2));
 76     return min(ans1,ans2);
 77 }
 78 
 79 int sgn(double x)
 80 {
 81     if(fabs(x) < eps)return 0;
 82     if(x < 0)return -1;
 83     else return 1;
 84 }
 85 
 86 double Get_angle(point a1,point a2,point b1,point b2)
 87 {
 88     point p1; p1.x=a1.x-a2.x; p1.y=a1.y-a2.y;
 89     point p2; p2.x=b1.x-b2.x; p2.y=b1.y-b2.y;
 90     return p1.x*p2.y-p1.y*p2.x;
 91 }
 92 
 93 double slove(point *p, int *ap, int &cp, point *q, int *aq, int &cq){
 94     int sp=0,sq=0;  double tmp;
 95     for(int i=0;i<cq;i++)  //max
 96     if(q[aq[i]].y-eps>q[aq[sq]].y) sq=i;
 97     double res=dist(p[ap[sp]],q[aq[sq]]);
 98     for(int i=0;i<cp;i++){
 99     //    while((tmp=fabs(multi(p[ap[i]],p[ap[i+1]],q[aq[sq]])/2)-fabs(multi(p[ap[i]],p[ap[i+1]],q[aq[(sq+1)%cq]])/2))>eps)
100     //    while(tmp=multi(p[ap[i]],p[ap[i+1]],q[aq[(sq+1)%cq]])-multi(p[ap[i]],p[ap[i+1]],q[aq[sq]])>eps)
101     //    sq=(sq+1)%cq;
102     //    if(tmp<-eps){
103          while(sgn(tmp = Get_angle(p[i],p[(i+1)%cp],q[sq],q[(sq+1)%cq])) < 0 )
104             sq = (sq + 1)%cq;
105         if(sgn(tmp) == 0)
106         res=min(res,pseg(p[ap[i]],p[ap[i+1]],q[aq[sq]]));
107     //    cout<<res<<endl;
108     //    }
109         else{
110         res=min(res,paral(p[ap[i]],p[ap[i+1]],q[aq[sq]],q[aq[(sq+1)%cq]]));
111     //    cout<<res<<endl;
112         }
113     }
114     return res;
115 }
116 
117 
118 int main(){
119     double ans=10000000;
120     while(scanf("%d%d",&n,&m)!=EOF){
121         if(n==0&&m==0) break;
122         for(int i=0;i<n;i++)
123         scanf("%lf%lf",&p[i].x,&p[i].y);
124         for(int i=0;i<m;i++)
125         scanf("%lf%lf",&q[i].x,&q[i].y);
126         sort(p,p+n,cmp);
127         sort(q,q+m,cmp);
128         forTU(p,n,ansp,cntp);
129         forTU(q,m,ansq,cntq);
130         ans=1e99;
131          ans=min(ans,slove(p,ansp,cntp,q,ansq,cntq));  //min,max
132          ans=min(ans,slove(q,ansq,cntq,p,ansp,cntp));
133          printf("%.5lf\n",ans);
134     }
135     return 0;
136 }
View Code

别人的代码:

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <math.h>using namespace std;const int N=50000;
const double eps=1e-9;
const double INF=1e99;struct Point
{double x,y;
};Point P[N],Q[N];double cross(Point A,Point B,Point C)
{return (B.x-A.x)*(C.y-A.y)-(B.y-A.y)*(C.x-A.x);
}double dist(Point A,Point B)
{return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}double multi(Point A,Point B,Point C)
{return (B.x-A.x)*(C.x-A.x)+(B.y-A.y)*(C.y-A.y);
}//顺时针排序
void anticlockwise(Point p[],int n)
{for(int i=0;i<n-2;i++){double tmp=cross(p[i],p[i+1],p[i+2]);if(tmp>eps) return;else if(tmp<-eps){reverse(p,p+n);return;}}
}//计算C点到直线AB的最短距离
double Getdist(Point A,Point B,Point C)
{if(dist(A,B)<eps) return dist(B,C);if(multi(A,B,C)<-eps) return dist(A,C);if(multi(B,A,C)<-eps) return dist(B,C);return fabs(cross(A,B,C)/dist(A,B));
}//求一条直线的两端点到另外一条直线的距离,反过来一样,共4种情况
double MinDist(Point A,Point B,Point C,Point D)
{return min(min(Getdist(A,B,C),Getdist(A,B,D)),min(Getdist(C,D,A),Getdist(C,D,B)));
}double Solve(Point P[],Point Q[],int n,int m)
{int yminP=0,ymaxQ=0;for(int i=0;i<n;i++)if(P[i].y<P[yminP].y)yminP=i;for(int i=0;i<m;i++)if(Q[i].y>Q[ymaxQ].y)ymaxQ=i;P[n]=P[0];Q[m]=Q[0];double tmp,ans=INF;for(int i=0;i<n;i++){while(tmp=cross(P[yminP+1],Q[ymaxQ+1],P[yminP])-cross(P[yminP+1],Q[ymaxQ],P[yminP])>eps)ymaxQ=(ymaxQ+1)%m;if(tmp<-eps) ans=min(ans,Getdist(P[yminP],P[yminP+1],Q[ymaxQ]));else         ans=min(ans,MinDist(P[yminP],P[yminP+1],Q[ymaxQ],Q[ymaxQ+1]));yminP=(yminP+1)%n;}return ans;
}int main()
{int n,m;while(cin>>n>>m){if(n==0&&m==0) break;for(int i=0;i<n;i++)cin>>P[i].x>>P[i].y;for(int i=0;i<m;i++)cin>>Q[i].x>>Q[i].y;anticlockwise(P,n);anticlockwise(Q,m);printf("%.5lf\n",min(Solve(P,Q,n,m),Solve(Q,P,m,n)));}return 0;
}

  

转载于:https://www.cnblogs.com/jie-dcai/p/3890912.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/473188.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

天池 在线编程 聪明的销售(计数+贪心)

文章目录1. 题目2. 解题1. 题目 销售主管的任务是出售一系列的物品&#xff0c;其中每个物品都有一个编号。 由于出售具有相同编号的商品会更容易&#xff0c;所以销售主管决定删除一些物品。 现在她知道她最多能删除多少物品&#xff0c;她想知道最终袋子里最少可以包含多少…

关于计算机书籍的收集与整理(一)

本文来源&#xff1a;https://github.com/pinefor1983/CS-Growing-book 一、程序员技术、管理和认知 1、程序员技术&管理 关于程序员职场晋升&#xff0c;这是我的7点具体建议优秀程序员的7个特点对码农后浪的6点建议程序员百万年薪进阶指南做好技术管理&#xff0c;你必须…

天池 在线编程 放小球(动态规划)

文章目录1. 题目2. 解题2.1 动态规划1. 题目 n 个桶中小球的个数已知, 可以操作 k 次(每次从桶中取出一个球,或者添加一个球), 每个桶有规定的最大容量 W[i]。 求操作后两相邻桶之间的最大差值的平方的最小值。 n < 100 W[i] < 100样例 1: 输入: 5 6 [1,2,3,4,5] [15,…

LeetCode 1716. 计算力扣银行的钱(等差数列)

文章目录1. 题目2. 解题1. 题目 Hercy 想要为购买第一辆车存钱。他 每天 都往力扣银行里存钱。 最开始&#xff0c;他在周一的时候存入 1 块钱。 从周二到周日&#xff0c;他每天都比前一天多存入 1 块钱。 在接下来每一个周一&#xff0c;他都会比 前一个周一 多存入 1 块钱…

LeetCode 1717. 删除子字符串的最大得分

文章目录1. 题目2. 解题374 / 1631&#xff0c;前22.9%1215 / 7873&#xff0c;前15.4%1. 题目 给你一个字符串 s 和两个整数 x 和 y 。你可以执行下面两种操作任意次。 删除子字符串 "ab" 并得到 x 分。 比方说&#xff0c;从 “cabxbae” 删除 ab &#xff0c;得…

利用Python把四张图片按照顺序拼接起来

一、需求&#xff1a; 给出四张图片&#xff0c;按照一定的顺序拼接起来 二、图片&#xff1a; 左上角&#xff1a;&#xff08;像素512*512&#xff09; 右上角&#xff1a;&#xff08;像素284*512&#xff09; 左下角&#xff1a;&#xff08;像素284*512&#xff09; 右…

Linux:文件创建时间如何修改?

一、需求 修改文件创建时间 二、知识及方法步骤 touch命令用于创建空白文件或修改文件时间。 在Linux系统中一个文件有三种时间&#xff1a; 更改内容的时间 - mtime&#xff1a;当文件进行被写的时候&#xff0c;CTime就会更新更改权限的时间 - ctime&#xff1a;当文件的…

小案例:编写立方体六个面,合成一张全景图后端

一、需求&#xff1a; 给出立方体六个面&#xff0c;合成一张全景图 二、主要知识&#xff1a;py360convert 2.1、该项目的特点&#xff1a; 立方体贴图和等矩形之间的转换 等角于平面 纯python实现&#xff0c;仅依赖于numpy和scipy矢量化实施&#xff08;在大多数地…

LeetCode 1721. 交换链表中的节点(快慢指针)

文章目录1. 题目2. 解题1. 题目 给你链表的头节点 head 和一个整数 k 。 交换 链表正数第 k 个节点和倒数第 k 个节点的值后&#xff0c;返回链表的头节点&#xff08;链表 从 1 开始索引&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], k 2 输出&am…

爬虫小案例:基于Bing关键词批量下载图片

一、需求&#xff1a; 基于Bing网站&#xff0c;输入关键词&#xff0c;批量下载图片保存到本地 二、演示&#xff1a; 三、直接上代码 import os import urllib.request import urllib.parse from bs4 import BeautifulSoup import re import time# 设置请求头 header {Us…

LeetCode 1722. 执行交换操作后的最小汉明距离(并查集)

文章目录1. 题目2. 解题1. 题目 给你两个整数数组 source 和 target &#xff0c;长度都是 n 。 还有一个数组 allowedSwaps &#xff0c;其中每个 allowedSwaps[i] [ai, bi] 表示你可以交换数组 source 中下标为 ai 和 bi&#xff08;下标从 0 开始&#xff09;的两个元素。…

线性表的顺序表示和实现

/* 顺序表存储结构容易实现随机存取线性表的第i 个数据元素的操作&#xff0c;但在实现插入、 删除的操作时要移动大量数据元素&#xff0c;所以&#xff0c;它适用于数据相对稳定的线性表&#xff0c;如职工工资 表、学生学籍表等。 c2-1.h 是动态分配的顺序表存储结构&#x…

LeetCode 1723. 完成所有工作的最短时间(DFS+剪枝 / 状态压缩DP)

文章目录1. 题目2. 解题2.1 DFS2.2 状态压缩DP265 / 3871&#xff0c; 前6.85% 前3题题解&#xff1a; LeetCode 5649. 解码异或后的数组&#xff08;位运算&#xff09;LeetCode 5652. 交换链表中的节点&#xff08;快慢指针&#xff09;LeetCode 5650. 执行交换操作后的最小…

win7优化设置_5项优化,至少提升20%!

Win7系统已经接近落幕的尾声了&#xff0c;不知大家是否早已做好准备了呢&#xff1f;很多朋友说win7不如win10好用&#xff0c;但马克思主义说到“新事物必将会取代旧事物”&#xff0c;也没必要一直坚守着win7的战线啦。自电脑升级了之后&#xff0c;便对win10系统进行了一些…

python实现两张图片横向和纵向拼接

本文实例为大家分享了python实现图片横向和纵向拼接的具体代码&#xff0c; 这里主要用Python扩展库pillow中Image对象的paste()方法把两张图片拼接起来供大家参考&#xff0c;具体内容如下&#xff1a; 一、代码&#xff1a; from PIL import Imagedef join(png1, png2, fl…

LeetCode 1203. 项目管理(两次拓扑排序)

文章目录1. 题目2. 解题1. 题目 公司共有 n 个项目和 m 个小组&#xff0c;每个项目要不无人接手&#xff0c;要不就由 m 个小组之一负责。 group[i] 表示第 i 个项目所属的小组&#xff0c;如果这个项目目前无人接手&#xff0c;那么 group[i] 就等于 -1。&#xff08;项目和…

BZOJ K大数查询(分治)(Zjoi2013)

题目链接&#xff1a;http://www.lydsy.com/JudgeOnline/problem.php?id3110 Description 有N个位置&#xff0c;M个操作。操作有两种&#xff0c;每次操作如果是1 a b c的形式表示在第a个位置到第b个位置&#xff0c;每个位置加入一个数c如果是2 a b c形式&#xff0c;表示询…

为什么电脑不能打字_为什么不能用电脑验光仪测出来的度数直接配眼镜?

当今世界&#xff0c;科学技术爆炸式发展和进步&#xff0c;很多人问我&#xff1a;“电脑验光仪的准确度越来越高&#xff0c;会不会取代人工验光师&#xff1f;”我们这代人从小听着学着“科学技术是第一生产力”长大的&#xff0c;自然是技术崇拜者&#xff0c;自然的反应当…

前端DEMO:网络上流行的抖音罗盘

一、效果&#xff1a; 二、关于代码&#xff1a; CSS/demo.css代码&#xff1a; * {margin: 0;padding: 0; } html, body {width: 100%;height: 100%;background-color: black;overflow: hidden; } #clock {position: relative;width: 100%;height: 100%;background: black; }…

[Kaggle] Sentiment Analysis on Movie Reviews(BERT)

文章目录1. 预训练模型下载2. 数据集3. 加载预训练模型4. 提交结果练习地址&#xff1a;https://www.kaggle.com/c/sentiment-analysis-on-movie-reviews 相关博文&#xff1a; [Kaggle] Spam/Ham Email Classification 垃圾邮件分类&#xff08;BERT&#xff09; 本文使用 hu…