梦,才是最真的现实

导航

poj 1066 计算几何构图+最短路

代码估计不用看了。。。。太长了,烦!纯粹是为了纪念一下我的三个多小时。。。。。。

说下怎么做好了,先用几何关系算出所有交点,然后根据交点求出所有可能的门(也就是同一条线上相邻两个交点点的中点),然后算一下门的关系,就是哪两个门是相邻的,最后,要求最短路,你懂的

#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);
}


posted on 2012-08-15 02:42  梦,才是最真的现实  阅读(158)  评论(0编辑  收藏  举报