很水的一题,但是改了好久都没改对。
原因是被定式思维害了,以为判断直线与点的位置只要返回个符号所以用int,但没想到负的double很小的时候变成int会成0,即丢失了原有符号。一直看了好几个小时才看出来。还是不够细致,这几天有点分心了。
/* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <queue> #define INF 1E9 using namespace std; struct node { double x,y; node(double a,double b) { x=a;y=b; } node(){} }; double dx[20],dy[20][4]; double dis[80][80]={0}; node pp[80]; int n,cnt; double d(node a,node b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double p(node a,node b,double x,double y)//小于0,点c在直线ab下,反之上方 { return (b.x-a.x)*(y-a.y)-(x-a.x)*(b.y-a.y); } bool isok(node a,node b) { int i,j; for(i=0;i<n&&dx[i]<=a.x;i++); bool flag=1; for(;i<n&&dx[i]<b.x;i++) { flag=0; for(j=0;j<4;j+=2) if(p(a,b,dx[i],dy[i][j])*p(a,b,dx[i],dy[i][j+1])<=0){flag=1;break;} if(!flag)return 0; } return 1; } bool input() { scanf("%d",&n); if(n==-1)return 0; int i,j; cnt=0; pp[cnt++]=node(0,5); for(i=0;i<n;i++) { scanf("%lf",&dx[i]); for(j=0;j<4;j++) { scanf("%lf",&dy[i][j]); pp[cnt++]=node(dx[i],dy[i][j]); } } pp[cnt++]=node(10,5); for(i=0;i<cnt;i++) { for(j=i;j<cnt;j++) { dis[i][j]=dis[j][i]=INF; if(pp[i].x==pp[j].x)continue; if(!isok(pp[i],pp[j]))continue; dis[i][j]=dis[j][i]=d(pp[i],pp[j]); // cout<<i<<" "<<j<<" "<<dis[i][j]<<endl; } } return 1; } double dd[80]; bool inq[80]; double solve() { int u,v; memset(dd,127,sizeof(dd)); memset(inq,0,sizeof(inq)); queue<int> q;q.push(0); dd[0]=0; double t; while(!q.empty()) { v=q.front();q.pop(); inq[v]=0; for(u=0;u<cnt;u++) if(dd[u]>(t=dd[v]+dis[v][u])) { dd[u]=t; if(inq[u])continue; q.push(u);inq[u]=1; } } return dd[cnt-1]; } int main() { while(input()) printf("%.2f\n",solve()); }