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) maxy=(maxy+1)%m;注释部分其实和非注释部分的程序转换过来是一样的,但运行结果却不一样

可能在同一个语句中不能进行太多的运算,要不然有可能会导致精度降低

总结就是以后在同一个语句中不要进行过多的运算,要分部分赋值

//最近点对和最远点对产生在有向平行切线上,将一条边平行过去,然后判断#include <iostream>#include <cstdlib>#include <cstdio>#include <cmath>#include<algorithm>using namespace std;const double eps=1e-8;struct Point {double x,y;Point (){}Point (double xx,double yy) {x=xx;y=yy;}Point operator -(const Point b)const {return Point(x-b.x,y-b.y);}double operator ^(const Point b)const {return x*b.y-y*b.x;}double operator *(const Point &b)const{return x*b.x + y*b.y;}};struct Line {Point s,e;double angle;Line(){}Line(Point ss,Point ee) {s=ss;e=ee;}};Point p[10005],q[10005],list[10005];int n,m,top,miny,maxy;double dist(Point a,Point b) {return sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));}//求点到线段距离,不是点到直线距离double pointtoseg(Point P,Point b,Point c){/*Line s=Line(b,c);Point mid;double t=(p-s.s)*(s.e-s.s)/((s.e-s.s)*(s.e-s.s));//s.s到垂点的距离/s.s到s.e的距离double ans;if(t>=0 && t<=1) {mid.x=s.s.x+(s.e.x-s.s.x)*t;mid.y=s.s.y+(s.e.y-s.s.y)*t;ans=dist(p,mid);}else {if(dist(p,s.s)<dist(p,s.e)) ans=dist(p,s.s);else ans=dist(p,s.e);}printf("%lf\n",ans);return ans;*/Point result;Line L=Line(b,c);double t = ((P-L.s)*(L.e-L.s))/((L.e-L.s)*(L.e-L.s));if(t >=0 && t <= 1){result.x = L.s.x + (L.e.x – L.s.x)*t;result.y = L.s.y + (L.e.y – L.s.y)*t;}else{if(dist(P,L.s) < dist(P,L.e))result = L.s;else result = L.e;}return dist(result,P);}double segtoseg(Point a,Point b,Point c,Point d){double ans1=min(pointtoseg(a,c,d),pointtoseg(b,c,d));double ans2=min(pointtoseg(c,a,b),pointtoseg(d,a,b));return min(ans1,ans2);}int cmp(Point a,Point b) {//逆时针double tmp=(a-list[0])^(b-list[0]);if(tmp == 0) return dist(a,list[0]) – dist(b,list[0]) <-eps;else return tmp>0;}void Graham(Point* p,Point* stack,int n){int k=0;for(int i=0;i<n;i++){if(p[i].y<p[k].y || (p[i].y==p[k].y && p[i].x<p[k].x)) k=i;}swap(p[0],p[k]);sort(p+1,p+n,cmp);if(n<=2){for(int i=0;i<n;i++) stack[i]=p[i];top=n;return;}stack[0]=p[0]; stack[1]=p[1];top=2;for(int i=2;i<n;i++){while(top>=2 && ((stack[top-1]-stack[top-2])^(p[i]-stack[top-2]))<eps) top–;stack[top++]=p[i];}}double Get_angle(Point a1,Point a2,Point b1,Point b2){return (a2-a1)^(b1-b2);}double rotating(Point* p,int n,Point* q,int m){miny=0,maxy=0;for(int i=0;i<n;i++) {if(p[i].y<p[miny].y) miny=i;}for(int i=0;i<m;i++) {if(q[i].y>q[maxy].y) maxy=i;}double ans=dist(p[miny],q[maxy]);for(int i=0;i<n;i++){double tmp;//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) maxy=(maxy+1)%m;if(fabs(tmp)<eps) ans=min(ans,segtoseg(p[miny],p[(miny+1)%n],q[maxy],q[(maxy+1)%m]));else ans=min(ans,pointtoseg(q[maxy],p[miny],p[(miny+1)%n]));miny=(miny+1)%n;}return ans;}int main() {#ifndef ONLINE_JUDGEfreopen("in.txt","r",stdin);#endif // ONLINE_JUDGEwhile(scanf("%d%d",&n,&m)) {if(n==0 && m==0) break;//顺时针排列的点miny=0,maxy=0;for(int i=0;i<n;i++) {scanf("%lf%lf",&list[i].x,&list[i].y);}Graham(list,p,n);n=top;for(int i=0;i<m;i++) {scanf("%lf%lf",&list[i].x,&list[i].y);}Graham(list,q,m);m=top;p[n]=p[0];q[m]=q[0];printf("%.5f\n",min(rotating(p,n,q,m),rotating(q,m,p,n)));}return 0;}

,人言未必皆真,听言只听三分。

POJ 3608 Bridge Across Islands

相关文章:

你感兴趣的文章:

标签云: