代码估计不用看了。。。。太长了,烦!纯粹是为了纪念一下我的三个多小时。。。。。。
说下怎么做好了,先用几何关系算出所有交点,然后根据交点求出所有可能的门(也就是同一条线上相邻两个交点点的中点),然后算一下门的关系,就是哪两个门是相邻的,最后,要求最短路,你懂的
#include<stdio.h> #include<string.h> #include<math.h> #include<vector> #include<queue> #include<algorithm> #define eps 1e-5 #define val 600 #define zero(x) (((x)>0?(x):-(x))<eps) using namespace std; typedef struct node {double x,y;int no;}point; typedef struct vode{point a,b;}line; typedef struct qode { int l, step; }position; bool map[val][val]; bool vis[val]; vector<point> data[val]; vector<line> LN; vector<point> in; int n,t; int solve(); point end; point intersection(line u,line v); int intersect_ex(line u,line v); int intersect_in(line u,line v); int same_side(point p1,point p2,line l); int dot_online_in(point p,line l); int opposite_side(point p1,point p2,line l); int dots_inline(point p1,point p2,point p3); double xmult(point p1,point p2,point p0); bool lessx(const point &s1,const point &s2) { if(!zero(s1.x-s2.x)) return s1.x<s2.x; else return s1.y<s2.y; } int main() { int ans,i,j; line p; point h,m; while(scanf("%d",&n)!=EOF) { LN.clear(); in.clear(); for(i=0;i<n+4;i++) data[i].clear(); p.a.x=0,p.a.y=0; p.b.x=0,p.b.y=100; LN.push_back(p); p.b.x=100,p.b.y=0; LN.push_back(p); p.a.x=100,p.a.y=0; p.b.x=100,p.b.y=100; LN.push_back(p); p.a.x=0,p.a.y=100; LN.push_back(p); for(i=4;i<n+4;i++) { scanf("%lf %lf %lf %lf",&p.a.x,&p.a.y,&p.b.x,&p.b.y); LN.push_back(p); } n+=4; /* for(i=0;i<n;i++) printf("(%.2lf,%.2lf) (%.2lf,%.2lf) \n",LN[i].a.x,LN[i].a.y,LN[i].b.x,LN[i].b.y);*/ scanf("%lf %lf",&end.x,&end.y); ans=solve(); printf("Number of doors = %d\n",ans); } return 0; } int solve() { int bfs(int ); int i,j,k,cnt=0,num; point sme,next; line L; in.clear(); memset(map,false,sizeof(map)); for(i=0;i<n;i++)//先来找出交点 for(j=i+1;j<n;j++) { // printf("I:%d j:%d ",i,j-4); if(intersect_in(LN[i],LN[j])) { // printf("FIND!"); sme=intersection(LN[i],LN[j]); data[i].push_back(sme); data[j].push_back(sme); } // putchar('\n'); } //printf("check:%d (%.2lf,%.2lf) (%.2lf,%.2lf) \n",intersect_in(LN[0],LN[6]),LN[6].a.x,LN[6].a.y,LN[6].b.x,LN[6].b.y); for(i=0;i<n;i++) sort(data[i].begin(),data[i].end(),lessx); for(i=0;i<n;i++) { for(j=0;j<data[i].size()-1;j++) { sme=data[i][j]; sme.no=cnt++; next=data[i][j+1]; sme.x=(sme.x+next.x)/2; sme.y=(sme.y+next.y)/2; in.push_back(sme); } } /* for(i=0;i<n;i++) { for(j=0;j<data[i].size();j++) printf("(%.2lf %.2lf) ",data[i][j].x,data[i][j].y); putchar('\n'); }*/ /* for(i=0;i<in.size();i++) printf("(%.2lf %.2lf) \n",in[i].x,in[i].y);*/ end.no=cnt++; in.push_back(end); for(i=0;i<in.size();i++) for(j=i+1;j<in.size();j++) { L.a=in[i],L.b=in[j]; for(k=0;k<n;k++) { if(intersect_in(L,LN[k])) if(!dots_inline(in[i],LN[k].a,LN[k].b)&&!dots_inline(in[j],LN[k].a,LN[k].b)) break; } if(k>=n) { // if(in[i].no==25) printf("J:%d\n",j); map[in[i].no][in[j].no]=map[in[j].no][in[i].no]=true; } } /* for(i=0;i<cnt;i++) { for(j=0;j<cnt;j++) { printf("%d ",map[i][j]); } putchar('\n'); }*/ num=bfs(cnt); return num; } int bfs(int cnt) { int i; queue<position>q; cnt--; position now,next; now.l=cnt; now.step=0; q.push(now); memset(vis,false,sizeof(vis)); while(!q.empty()) { now=q.front(); // printf("NOW: %d (%.2lf,%.2lf) \n",now.l,in[now.l].x,in[now.l].y); if(zero(in[now.l].x)||zero(in[now.l].y)||zero(in[now.l].x-100)||zero(in[now.l].y-100)) { // printf("FFFFFFFFFFINF!\n"); return now.step; } q.pop(); next.step=now.step+1; for(i=0;i<=cnt;i++) { if(vis[i]) continue; next.l=i; if(map[now.l][i]) { q.push(next); vis[i]=true; } } } return 1111111; } point intersection(line u,line v){ point ret=u.a; double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x)) /((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x)); ret.x+=(u.b.x-u.a.x)*t; ret.y+=(u.b.y-u.a.y)*t; return ret; } int intersect_ex(line u,line v){ return opposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u); } int intersect_in(line u,line v){ if (!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b)) return !same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u); return dot_online_in(u.a,v)||dot_online_in(u.b,v)||dot_online_in(v.a,u)||dot_online_in(v.b,u); } int same_side(point p1,point p2,line l){ return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps; } int dot_online_in(point p,line l){ return zero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&&(l.a.y-p.y)*(l.b.y-p.y)<eps; } int opposite_side(point p1,point p2,line l){ return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)<-eps; } int dots_inline(point p1,point p2,point p3){ return zero(xmult(p1,p2,p3)); } 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); }