poj 3608 Bridge Across Islands 两凸包间最近距离


  1 /**
2 旋转卡壳,,
3 **/
4 #include <iostream>
5 #include <algorithm>
6 #include <cmath>
7 #include <cstdio>
8 using namespace std;
9
10 const double eps = 1e-8;
11 struct point {
12 double x,y;
13 point(double x=0,double y =0):x(x),y(y){}
14 };
15
16 int dcmp(double x){
17 if(fabs(x)<eps)
18 return 0;
19 else
20 return x<0?-1:1;
21 }
22
23 point p[10020],p1[10020];
24 point q[10020],q1[10020];
25 int maxid,minid;
26 int N,M;
27 typedef point Vector;
28
29 Vector operator -(point a,point b){
30 return Vector(a.x-b.x,a.y-b.y);
31 }
32
33 double cross(Vector a,Vector b){
34 return a.x*b.y-a.y*b.x;
35 }
36
37 double dot(Vector a,Vector b){
38 return a.x*b.x+a.y*b.y;
39 }
40 bool cmp(point a,point b){
41 if(a.x==b.x)
42 return a.y<b.y;
43 return a.x<b.x;
44 }
45
46 bool operator ==(const point &a,const point &b){
47 return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
48 }
49
50 double length(Vector a){
51 return sqrt(a.x*a.x+a.y*a.y);
52 }
53
54 int convexHull(point *p,int n,point *ch){
55 sort(p,p+n,cmp);
56 int m =0;
57 for(int i=0;i<n;i++){
58 while(m>1&&cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)
59 m--;
60 ch[m++] = p[i];
61 }
62 int k =m;
63 for(int i = n-2;i>=0;i--){
64 while(m>k&&cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)
65 m--;
66 ch[m++] = p[i];
67 }
68 if(n>1) m--;
69 return m;
70 }
71
72 double distanceToSegment(point p,point a,point b){
73 if(a==b)
74 return length(p-a);
75 Vector v1 = b-a,v2 = p-a, v3 = p-b;
76 if(dcmp(dot(v1,v2))<0)
77 return length(v2);
78 else if(dcmp(dot(v1,v3))>0)
79 return length(v3);
80 else
81 return fabs(cross(v1,v2))/length(v1);
82 }
83
84 double distanceBetweenSegment(point a,point b,point c,point d){
85 return min(min(distanceToSegment(a,c,d),distanceToSegment(b,c,d)),min(distanceToSegment(c,a,b),distanceToSegment(d,a,b)));
86 }
87
88 void getMaxAndMin(int &maxid,int &minid){
89 maxid =0;
90 minid =0;
91 for(int i=1;i<N;i++){
92 if(p1[i].y<p1[minid].y)
93 minid =i;
94 }
95 for(int i=0;i<M;i++){
96 if(q1[i].y>q1[maxid].y)
97 maxid = i;
98 }
99 }
100
101 double solve(point *p,point *q,int minid,int maxid,int N,int M){
102 double temp,ret = 1e5;
103 p[N] = p[0];
104 q[M] = q[0];
105 for(int i=0;i<N;i++){
106 while(temp = dcmp(cross(q[maxid]-q[maxid+1],p[minid+1]-p[minid]))>0){
107 maxid = (maxid+1)%M;
108 }
109 if(temp<0)
110 ret = min(ret,distanceToSegment(q[maxid],p[minid],p[minid+1]));
111 else
112 ret = min(ret,distanceBetweenSegment(p[minid],p[minid+1],q[maxid],q[maxid+1]));
113 minid = (minid+1)%N;
114 }
115 return ret;
116 }
117
118 int main()
119 {
120
121 while(cin>>N>>M){
122 if(N==0&&M==0)
123 break;
124 for(int i=0;i<N;i++)
125 cin>>p[i].x>>p[i].y;
126 for(int i=0;i<M;i++)
127 cin>>q[i].x>>q[i].y;
128 N = convexHull(p,N,p1);
129 M = convexHull(q,M,q1);
130 getMaxAndMin(maxid,minid);
131 double ans = solve(p1,q1,minid,maxid,N,M);
132 printf("%.5lf\n",ans);
133 }
134 return 0;
135 }

poj 3608 Bridge Across Islands 两凸包间最近距离

时间: 2024-10-13 00:17:55

poj 3608 Bridge Across Islands 两凸包间最近距离的相关文章

poj 3608(旋转卡壳求解两凸包之间的最短距离)

Bridge Across Islands Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9768   Accepted: 2866   Special Judge Description Thousands of thousands years ago there was a small kingdom located in the middle of the Pacific Ocean. The territory

POJ 3608 Bridge Across Islands --凸包间距离

题意: 给你两个凸包,求其最短距离. 解法: POJ 我真的是弄不懂了,也不说一声点就是按顺时针给出的,不用调整点顺序. 还是说数据水了,没出乱给点或给逆时针点的数据呢..反正WA了几发就是了. 求凸包最短距离还是用旋转卡壳的方法,这里采用的是网上给出的一种方法: 英文版:        http://cgm.cs.mcgill.ca/~orm/mind2p.html 中文翻译版:  http://www.cnblogs.com/bless/archive/2008/08/06/1262438.

POJ 3608 Bridge Across Islands

WA了好多次 说一下错误 第一个地方是旋转卡壳是要进行两次的 第二个地方其实也不算错误,应该是程序运行的精度问题 在下面这部分程序中 //while((tmp=(p[(miny+1)%n]-p[miny])^(p[maxy]-p[(maxy+1)%m]))<-eps) maxy=(maxy+1)%m;//只要在向量miny-miny+1右侧则说明在向对踵点对的方向靠 while((tmp=Get_angle(p[miny],p[miny+1],q[maxy],q[maxy+1]))<-eps)

sql 计算两经纬度间的距离

DECLARE @g geography;SET @g = geography::STPointFromText('POINT(113.216273 23.236333)', 4326);SELECT @g.ToString();DECLARE @gg geography;SET @gg = geography::STPointFromText('POINT(115.567368 37.341209)', 4326);SELECT @gg.ToString(); SELECT @g.STDist

poj 3068 Bridge Across Islands

Bridge Across Islands Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11196   Accepted: 3292   Special Judge Description Thousands of thousands years ago there was a small kingdom located in the middle of the Pacific Ocean. The territory

【poj3608】 Bridge Across Islands

http://poj.org/problem?id=3608 (题目链接) 题意:求两凸包间最短距离 Solution  难写难调,旋转卡壳,还真是卡死我了.  先分别选出两凸包最上点和最下点,从这两点开始向逆时针方向旋转卡壳.用叉乘判断是否旋转旋转,具体操作跟求凸包直径差不多. poj discuss蒯下来的数据制造器: #include<algorithm> #include<iostream> #include<cstdlib> #include<cstdi

POJ 3608 两凸包最近距离 旋转卡壳

Bridge Across Islands Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8071   Accepted: 2364   Special Judge Description Thousands of thousands years ago there was a small kingdom located in the middle of the Pacific Ocean. The territory

【POJ 3608】Bridge Across Islands

Bridge Across Islands Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8853   Accepted: 2603   Special Judge Description Thousands of thousands years ago there was a small kingdom located in the middle of the Pacific Ocean. The territory

POJ 3608

1.计算P上y坐标值最小的顶点(称为 yminP )和Q上y坐标值最大的顶点(称为 ymaxQ). 2.为多边形在 yminP 和 ymaxQ 处构造两条切线 LP 和 LQ 使得他们对应的多边形位于他们的右侧.   此时 LP 和 LQ 拥有不同的方向, 并且 yminP 和 ymaxQ 成为了多边形间的一个对踵点对. 3.计算距离(yminP,ymaxQ) 并且将其维护为当前最小值. 4.顺时针同时旋转平行线直到其中一个与其所在的多边形的边重合. 5.如果只有一条线与边重合, 那么只需要计算