这题算法十分诡异。。只是抄了个板子还是不能够很好地理解。。tm都不敢说是原创的了。。。
这个是取了A凸包的最低点和B凸包的最高点,作用。。。个人感觉就是保证第一次找的时候是最近点,以便后续进行下去。。然后在A凸包上找点,在B凸包上找边,枚举边,然后在A凸包逆时针找最近点。。由于B凸包边的枚举顺序也是逆时针,所以可以分开枚举。。然后复杂度就降到O(n)了。。
更具体的可以去百度。。毕竟窝也挺迷的。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<stack>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define inf 10000
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-8
#define succ(x) (1<<x)
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define mid (x+y>>1)
#define NM 100005
#define nm 100498
#define pi 3.1415926535897931
using namespace std;
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f*x;
}
struct P{
double x,y;
P(double x=0,double y=0):x(x),y(y){}
P operator-(const P&o){return P(x-o.x,y-o.y);}
double operator*(const P&o){return x*o.y-y*o.x;}
double operator%(const P&o){return x*o.x+y*o.y;}
}a[NM],b[NM];
double dis(P o){return sqrt(sqr(o.x)+sqr(o.y));}
int n,m;
double ans;
double getd(P a,P b,P c){
if((b-c)%(a-c)<-eps)return dis(a-c);
if((c-b)%(a-b)<-eps)return dis(a-b);
return fabs((a-b)*(c-b))/dis(b-c);
}
double lined(P a,P b,P c,P d){return min(min(getd(a,c,d),getd(b,c,d)),min(getd(c,a,b),getd(d,a,b)));}
void rorate(P a[],P b[],int n,int m){
int i=1,j=1,tmp;
a[n+1]=a[i];b[m+1]=b[1];
inc(k,1,n)if(a[k].y<a[i].y)i=k;
inc(k,1,m)if(b[k].y>b[j].y)j=k;
inc(k,1,n){
while(tmp=(b[j+1]-a[i])*(a[i+1]-a[i])-(b[j]-a[i])*(a[i+1]-a[i])>eps)j=j%m+1;
if(tmp<-eps)ans=min(ans,getd(b[j],a[i],a[i+1]));
else ans=min(ans,lined(b[j],b[j+1],a[i],a[i+1]));
//printf("%lf\n",ans);
i=i%n+1;
}
}
int main(){
//freopen("data.in","r",stdin);
while(n=read()){
m=read();ans=inf;
dec(i,n,1)scanf("%lf%lf",&a[i].x,&a[i].y);
dec(i,m,1)scanf("%lf%lf",&b[i].x,&b[i].y);
rorate(a,b,n,m);
rorate(b,a,m,n);
printf("%lf\n",ans);
}
return 0;
}
Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 11544 | Accepted: 3400 | Special Judge |
Description
Thousands of thousands years ago there was a small kingdom located in the middle of the Pacific Ocean. The territory of the kingdom consists two separated islands. Due to the impact of the ocean current, the shapes of both the islands became convex polygons. The king of the kingdom wanted to establish a bridge to connect the two islands. To minimize the cost, the king asked you, the bishop, to find the minimal distance between the boundaries of the two islands.
Input
The input consists of several test cases.
Each test case begins with two integers N, M. (3 ≤ N, M ≤ 10000)
Each of the next N lines contains a pair of coordinates, which describes the position of a vertex in one convex polygon.
Each of the next M lines contains a pair of coordinates, which describes the position of a vertex in the other convex polygon.
A line with N = M = 0 indicates the end of input.
The coordinates are within the range [-10000, 10000].
Output
For each test case output the minimal distance. An error within 0.001 is acceptable.
Sample Input
4 4 0.00000 0.00000 0.00000 1.00000 1.00000 1.00000 1.00000 0.00000 2.00000 0.00000 2.00000 1.00000 3.00000 1.00000 3.00000 0.00000 0 0
Sample Output
1.00000
Source
[Submit] [Go Back] [Status] [Discuss]