hdu2823 2010.3.6

来源:互联网 发布:文豪野犬 知乎 编辑:程序博客网 时间:2024/06/17 09:14

hdu2823 2010.3.6

The widest road

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 72    Accepted Submission(s): 13

 

 

Problem Description

There were two families in the village —family A and family B, while these two families didn’t get along well with eachother. Now the head of the village decided to make a road through the villageand it must be straight, for a straight line makes the way shortest andmeanwhile, saves the cost. At that time, the heads of the two familiesproposed, because they didn’t want their own families live separated along thetwo sides of the road, thus it might decrease the solidarity of family. Besides,the two families were antipathetic to each other; neither wanted to livetogether with the other in a same side of the road. Then it made the villagehead in a pickle, he hoped the road to be as wide as possible. So what’s thepossible maximal width of this road?

In order to simplify the problem, let’sregard the living place of each family member is just a point.

 

 

 

Input

There are several test cases in the input.

 

The first line of each input contains n andm (1 ≤ m,n ≤ 1000). As for the following n lines, there are two numbers in everyline, representing the living places of A family members. And the following mlines represent the living places of B family members.

 

 

Output

The output numbers of each line are themaximal width of the road (retain four decimal), while if it’s impossible tomake such a road, then just output 0.0000.

 

 

Sample Input

3 3

0.0 0.0

1.0 0.0

0.0 1.0

4.0 0.0

5.0 0.0

4.0 1.0

 

 

Sample Output

3.0000

 

 

Source

2009 Multi-University Training Contest 1 -Host by TJU

 

 

Recommend

gaojie

 

#include <math.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#define eps 1e-8#define zero(x) (((x)>0?(x):-(x))<eps)#define _sign(x) ((x)>eps?1:((x)<-eps?2:0))struct point{double x,y;};//计算cross product (P1-P0)x(P2-P0)double xmult(point p1,point p2,point p0){return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}//graham算法顺时针构造包含所有共线点的凸包,O(nlogn)point p1,p2;int graham_cp(const void* a,const void* b){double ret=xmult(*((point*)a),*((point*)b),p1);return zero(ret)?(xmult(*((point*)a),*((point*)b),p2)>0?1:-1):(ret>0?1:-1);}void _graham(int n,point* p,int& s,point* ch){int i,k=0;for (p1=p2=p[0],i=1;i<n;p2.x+=p[i].x,p2.y+=p[i].y,i++)if (p1.y-p[i].y>eps||(zero(p1.y-p[i].y)&&p1.x>p[i].x))p1=p[k=i];p2.x/=n,p2.y/=n;p[k]=p[0],p[0]=p1;qsort(p+1,n-1,sizeof(point),graham_cp);for (ch[0]=p[0],ch[1]=p[1],ch[2]=p[2],s=i=3;i<n;ch[s++]=p[i++])for (;s>2&&xmult(ch[s-2],p[i],ch[s-1])<-eps;s--);}//构造凸包接口函数,传入原始点集大小n,点集p(p原有顺序被打乱!)//返回凸包大小,凸包的点在convex中//参数maxsize为1包含共线点,为0不包含共线点,缺省为1//参数clockwise为1顺时针构造,为0逆时针构造,缺省为1//在输入仅有若干共线点时算法不稳定,可能有此类情况请另行处理!//不能去掉点集中重合的点int graham(int n,point* p,point* convex,int maxsize=1,int dir=1){point* temp=new point[n];int s,i;_graham(n,p,s,temp);for (convex[0]=temp[0],n=1,i=(dir?1:(s-1));dir?(i<s):i;i+=(dir?1:-1))if (maxsize||!zero(xmult(temp[i-1],temp[i],temp[(i+1)%s])))convex[n++]=temp[i];delete []temp;return n;}//两点距离double distance(point p1,point p2){return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));}//点到线段距离double disptoseg(point p,point l1,point l2){point t=p;t.x+=l1.y-l2.y,t.y+=l2.x-l1.x;if (xmult(l1,t,p)*xmult(l2,t,p)>eps)return distance(p,l1)<distance(p,l2)?distance(p,l1):distance(p,l2);return fabs(xmult(p,l1,l2))/distance(l1,l2);}//判三点共线int dots_inline(point p1,point p2,point p3){return zero(xmult(p1,p2,p3));}//判两点在线段同侧,点在线段上返回0int same_side(point p1,point p2,point l1,point l2){return xmult(l1,p1,l2)*xmult(l1,p2,l2)>eps;}//判点是否在线段上,包括端点int dot_online_in(point p,point l1,point l2){return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;}//判两线段相交,包括端点和部分重合int intersect_in(point u1,point u2,point v1,point v2){if (!dots_inline(u1,u2,v1)||!dots_inline(u1,u2,v2))return !same_side(u1,u2,v1,v2)&&!same_side(v1,v2,u1,u2);return dot_online_in(u1,v1,v2)||dot_online_in(u2,v1,v2)||dot_online_in(v1,u1,u2)||dot_online_in(v2,u1,u2);}//判点在凸多边形内或多边形边上,顶点按顺时针或逆时针给出int inside_convex(point q,int n,point* p){int i,s[3]={1,1,1};for (i=0;i<n&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],q,p[i]))]=0;return s[1]|s[2];}void solve(int a,int b,point ca[],point cb[]){double tmp,ret;if(a==1&&b==1){printf("%.4lf\n",distance(ca[0],cb[0]));return;}if(a==1&&b==2){printf("%.4lf\n",disptoseg(ca[0],cb[0],cb[1]));return;}if(a==2&&b==1){printf("%.4lf\n",disptoseg(cb[0],ca[0],ca[1]));return;}if(a==2&&b==2){if(intersect_in(ca[0],ca[1],cb[0],cb[1])==1){printf("0.0000\n");return;}ret=1000000000;tmp=disptoseg(ca[0],cb[0],cb[1]);if(tmp<ret)ret=tmp;tmp=disptoseg(ca[1],cb[0],cb[1]);if(tmp<ret)ret=tmp;tmp=disptoseg(cb[0],ca[0],ca[1]);if(tmp<ret)ret=tmp;tmp=disptoseg(cb[1],ca[0],ca[1]);if(tmp<ret)ret=tmp;printf("%.4lf\n",ret);return;}if(a==1&&b>=3){if(inside_convex(ca[0],b,cb)==1){printf("0.0000\n");return;}ret=1000000000;for(int i=0;i<b-1;i++){tmp=disptoseg(ca[0],cb[i],cb[i+1]);if(tmp<ret)ret=tmp;}tmp=disptoseg(ca[0],cb[0],cb[b-1]);if(tmp<ret)ret=tmp;printf("%.4lf\n",ret);return;}if(a>=3&&b==1){if(inside_convex(cb[0],a,ca)==1){printf("0.0000\n");return;}ret=1000000000;for(int i=0;i<a-1;i++){tmp=disptoseg(cb[0],ca[i],ca[i+1]);if(tmp<ret)ret=tmp;}tmp=disptoseg(cb[0],ca[0],ca[a-1]);if(tmp<ret)ret=tmp;printf("%.4lf\n",ret);return;}if(a==2&&b>=3){if(inside_convex(ca[0],b,cb)==1||inside_convex(ca[1],b,cb)==1){printf("0.0000\n");return;}for(int i=0;i<b-1;i++){if(intersect_in(ca[0],ca[1],cb[i],cb[i+1])==1){printf("0.0000\n");return;}}if(intersect_in(ca[0],ca[1],cb[0],cb[b-1])==1){printf("0.0000\n");return;}ret=1000000000;for(int i=0;i<a;i++){for(int j=0;j<b-1;j++){tmp=disptoseg(ca[i],cb[j],cb[j+1]);if(tmp<ret)ret=tmp;}tmp=disptoseg(ca[i],cb[0],cb[b-1]);if(tmp<ret)ret=tmp;}for(int i=0;i<b;i++){for(int j=0;j<a-1;j++){tmp=disptoseg(cb[i],ca[j],ca[j+1]);if(tmp<ret)ret=tmp;}tmp=disptoseg(cb[i],ca[0],ca[a-1]);if(tmp<ret)ret=tmp;}printf("%.4lf\n",ret);return;}if(a>=3&&b==2){if(inside_convex(cb[0],a,ca)==1||inside_convex(cb[1],a,ca)==1){printf("0.0000\n");return;}for(int i=0;i<a-1;i++){if(intersect_in(cb[0],cb[1],ca[i],ca[i+1])==1){printf("0.0000\n");return;}}if(intersect_in(cb[0],cb[1],ca[0],ca[a-1])==1){printf("0.0000\n");return;}ret=1000000000;for(int i=0;i<a;i++){for(int j=0;j<b-1;j++){tmp=disptoseg(ca[i],cb[j],cb[j+1]);if(tmp<ret)ret=tmp;}tmp=disptoseg(ca[i],cb[0],cb[b-1]);if(tmp<ret)ret=tmp;}for(int i=0;i<b;i++){for(int j=0;j<a-1;j++){tmp=disptoseg(cb[i],ca[j],ca[j+1]);if(tmp<ret)ret=tmp;}tmp=disptoseg(cb[i],ca[0],ca[a-1]);if(tmp<ret)ret=tmp;}printf("%.4lf\n",ret);return;}if(a>=3&&b>=3){for(int i=0;i<a;i++){if(inside_convex(ca[i],b,cb)==1){printf("0.0000\n");return;}}for(int i=0;i<b;i++){if(inside_convex(cb[i],a,ca)==1){printf("0.0000\n");return;}}for(int i=0;i<a-1;i++){for(int j=0;j<b-1;j++){if(intersect_in(ca[i],ca[i+1],cb[j],cb[j+1])==1){printf("0.0000\n");return;}}if(intersect_in(ca[i],ca[i+1],cb[0],cb[b-1])==1){printf("0.0000\n");return;}}for(int i=0;i<b-1;i++){if(intersect_in(ca[0],ca[a-1],cb[i],cb[i+1])==1){printf("0.0000\n");return;}}if(intersect_in(ca[0],ca[a-1],cb[0],cb[b-1])==1){printf("0.0000\n");return;}ret=1000000000;for(int i=0;i<a;i++){for(int j=0;j<b-1;j++){tmp=disptoseg(ca[i],cb[j],cb[j+1]);if(tmp<ret)ret=tmp;}tmp=disptoseg(ca[i],cb[0],cb[b-1]);if(tmp<ret)ret=tmp;}for(int i=0;i<b;i++){for(int j=0;j<a-1;j++){tmp=disptoseg(cb[i],ca[j],ca[j+1]);if(tmp<ret)ret=tmp;}tmp=disptoseg(cb[i],ca[0],ca[b-1]);if(tmp<ret)ret=tmp;}printf("%.4lf\n",ret);return;}}int main(){int n,m,a,b;point pa[1005],pb[1005],ca[1005],cb[1005];while(scanf("%d%d",&n,&m)!=EOF){for(int i=0;i<n;i++)scanf("%lf%lf",&pa[i].x,&pa[i].y);for(int i=0;i<m;i++)scanf("%lf%lf",&pb[i].x,&pb[i].y);if(n<3){for(int i=0;i<n;i++)ca[i]=pa[i];a=n;}if(m<3){for(int i=0;i<m;i++)cb[i]=pb[i];b=m;}if(n>=3){a=graham(n,pa,ca,0);if(a==1){ca[a]=pa[a];a++;}}if(m>=3){b=graham(m,pb,cb,0);if(b==1){cb[b]=pb[b];b++;}}solve(a,b,ca,cb);}return 0;}

0 0
原创粉丝点击