代码估计不用看了。。。。太长了,烦!纯粹是为了纪念一下我的三个多小时。。。。。。
说下怎么做好了,先用几何关系算出所有交点,然后根据交点求出所有可能的门(也就是同一条线上相邻两个交点点的中点),然后算一下门的关系,就是哪两个门是相邻的,最后,要求最短路,你懂的
#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);
}