poj 1066 Treasure Hunt 线段相交

题意:给出一个100*100的正方形区域,有若干端点在区域边界的线段是墙,然后给出宝藏位置,要求从区域外部开辟到宝藏所在位置的一条路径,使得开辟路径所需要打通的墙壁数最少("打通一堵墙"即在墙壁所在线段中间位置开一空间以连通外界),输出应打通墙壁的个数(包括边界上墙壁)。

 

思路:因为墙的端点都在区域边界上,所以从区域外部到宝藏所在位置的路径一定是直线。

可以枚举每个入口,和宝藏位置连成线段,输出与给定线段交点个数的最小值+1。(严格相交)

入口可以选取所有线段的端点。

n=0 输出1

 

 1 #include<iostream>
2 #include<cmath>
3 using namespace std;
4 #define MAXN 70
5 #define EPS 1e-8
6 struct point
7 {
8 double x,y;
9 point(){}
10 point(double x0,double y0): x(x0),y(y0){}
11 };
12 point a[MAXN],des;
13 int n;
14 int top;
15 point operator -(const point &p,const point &q)
16 {
17 point ans;
18 return point(p.x-q.x,p.y-q.y);
19 }
20 int dblcmp(double p)
21 {
22 if(fabs(p)<EPS) return 0;
23 return (p>0) ? 1:-1;
24 }
25 double cross(point p1,point p2)
26 {
27 return p1.x*p2.y-p1.y*p2.x;
28 }
29 bool is_intersect(point p1,point p2,point p3,point p4)
30 {
31 return dblcmp(cross(p1-p3,p4-p3))*dblcmp(cross(p2-p3,p4-p3))==-1;
32 }
33 int solve()
34 {
35 int i,j,res,min=(1<<30);
36 for(i=1;i<=top;i++)
37 {
38 res=0;
39 for(j=1;j<=top;j+=2)
40 if(is_intersect(des,a[i],a[j],a[j+1])) res++;
41 if(min>res) min=res;
42 }
43 if(min>MAXN) return 1;
44 return min+1;
45 }
46 int main()
47 {
48 scanf("%d",&n);
49 int i;
50 for(i=1;i<=n;i++)
51 {
52 scanf("%lf%lf%lf%lf",&a[top+1].x,&a[top+1].y,&a[top+2].x,&a[top+2].y);
53 top+=2;
54 }
55 scanf("%lf%lf",&des.x,&des.y);
56 printf("Number of doors = %d\n",solve());
57 return 0;
58 }



posted on 2012-02-19 10:33  myoi  阅读(211)  评论(0编辑  收藏  举报

导航