poj1066Treasure Hunt(线段相交)

链接

很纠结的找到了所有线段的中点,又很纠结的找到了哪些中点可以直接相连,最后bfs一下求出了最短路。。

  1 #include <iostream>

  2 #include<cstdio>

  3 #include<cstring>

  4 #include<algorithm>

  5 #include<stdlib.h>

  6 #include<vector>

  7 #include<cmath>

  8 #include<queue>

  9 #include<set>

 10 using namespace std;

 11 #define N 2210

 12 #define LL long long

 13 #define INF 0xfffffff

 14 const double eps = 1e-10;

 15 const double inf = ~0u>>2;

 16 vector<int>ed[N];

 17 struct Point

 18 {

 19     double x,y;

 20     Point(double x=0,double y=0):x(x),y(y) {} //构造函数 方便代码编写

 21 } p[105],q[N];

 22 int g,dis[N];

 23 bool vis[N];

 24 vector<Point>pi[N];

 25 typedef Point pointt;

 26 pointt operator + (Point a,Point b)

 27 {

 28     return Point(a.x+b.x,a.y+b.y);

 29 }

 30 pointt operator - (Point a,Point b)

 31 {

 32     return Point(a.x-b.x,a.y-b.y);

 33 }

 34 pointt operator * (Point a,double b)

 35 {

 36     return Point(a.x*b,a.y*b);

 37 }

 38 pointt operator / (Point a,double b)

 39 {

 40     return Point(a.x/b,a.y/b);

 41 }

 42 bool operator < (const Point &a,const Point &b)

 43 {

 44     return a.x<b.x||(a.x==b.x&&a.y<b.y);

 45 }

 46 int dcmp(double x)

 47 {

 48     if(fabs(x)<eps) return 0;

 49     else return x<0?-1:1;

 50 }

 51 double cross(Point a,Point b)

 52 {

 53     return a.x*b.y-a.y*b.x;

 54 }

 55 Point intersection1(Point a,Point b,Point c,Point d)//直线交点求解

 56 {

 57     Point pp = a;

 58     double t = ((a.x-c.x)*(c.y-d.y)-(a.y-c.y)*(c.x-d.x))/

 59                ((a.x-b.x)*(c.y-d.y)-(a.y-b.y)*(c.x-d.x));

 60     pp.x+=(b.x-a.x)*t;

 61     pp.y+=(b.y-a.y)*t;

 62     return pp;

 63 }

 64 bool seginter(pointt a1,pointt a2,pointt b1,pointt b2)

 65 {

 66     double c1 = cross(a2-a1,b1-a1),c2 = cross(a2-a1,b2-a1),

 67                                         c3 = cross(b2-b1,a1-b1),c4 = cross(b2-b1,a2-b1);

 68     return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;

 69 }

 70 void init(int i,int n)

 71 {

 72     p[i+1].x = 0;

 73     p[i+1].y = 0;

 74     p[i+2].x = 0;

 75     p[i+2].y = 100;

 76     p[i+3].x = 100;

 77     p[i+3].y = 100;

 78     p[i+4].x = 100;

 79     p[i+4].y = 0;

 80     p[i+1+n] = p[i+2];

 81     p[i+2+n] = p[i+3];

 82     p[i+3+n] = p[i+4];

 83     p[i+4+n] = p[i+1];

 84 

 85 }

 86 int judge(int x)

 87 {

 88     if(fabs(q[x].x)<eps||fabs(q[x].y)<eps||fabs(q[x].x-100.0)<eps||fabs(q[x].y-100.0)<eps)

 89         return 1;

 90     return 0;

 91 }

 92 void bfs(int st)

 93 {

 94     queue<int>Q;

 95     Q.push(st);

 96     memset(vis,0,sizeof(vis));

 97    // cut<<

 98     for(int i = 0 ; i <= st ; i++)

 99         dis[i] = INF;

100     dis[st] = 0;

101     while(!Q.empty())

102     {

103         int u = Q.front();

104         Q.pop();

105         //printf("%.2f %.2f %d\n",q[u].x,q[u].y,dis[u]);

106         if(judge(u))

107         {

108             printf("Number of doors = %d\n",dis[u]);

109             break;

110         }

111         for(int i =0 ; i < ed[u].size() ; i++)

112         {

113             int v = ed[u][i];

114             //cout<<v<<" "<<dis[u]<<endl;

115             dis[v] = min(dis[v],dis[u]+1);

116             if(!vis[v])

117             {

118                 vis[v] = 1;

119                 Q.push(v);

120             }

121         }

122     }

123 }

124 bool cmp(Point a,Point b)

125 {

126     if(fabs(a.x-b.x)<eps)

127         return a.y<b.y;

128     return a.x<b.x;

129 }

130 int main()

131 {

132     int n,i,j,e;

133     scanf("%d",&n);

134 //    while(scanf("%d",&n)!=EOF)

135 //    {

136         n+=4;

137         g = 0;

138         for(i = 1; i <= n-4 ; i++)

139         {

140             scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i+n].x,&p[i+n].y);

141         }

142         init(n-4,n);

143         for(i = 1; i <= n-4; i++)

144         {

145             for(j = 1; j <= n-4 ; j++)

146             {

147                 if(i==j) continue;

148                 if(seginter(p[i],p[i+n],p[j],p[j+n]))

149                 {

150                     pi[i].push_back(intersection1(p[i],p[i+n],p[j],p[j+n]));

151                 }

152             }

153         }

154         for(i = 1 ; i <= n-4 ; i++)

155         {

156             if(dcmp(p[i].x)==0)

157                 pi[n-3].push_back(p[i]);

158             if(dcmp(p[i+n].x)==0)

159                 pi[n-3].push_back(p[i+n]);

160             if(dcmp(p[i].y-100)==0)

161                 pi[n-2].push_back(p[i]);

162             if(dcmp(p[i+n].y-100)==0)

163                 pi[n-2].push_back(p[i+n]);

164             if(dcmp(p[i].x-100)==0)

165                 pi[n-1].push_back(p[i]);

166             if(dcmp(p[i+n].x-100)==0)

167                 pi[n-1].push_back(p[i+n]);

168             if(dcmp(p[i].y)==0)

169                 pi[n].push_back(p[i]);

170             if(dcmp(p[i+n].y)==0)

171                 pi[n].push_back(p[i+n]);

172         }

173         for(i = 1 ; i <= n; i++)

174         {

175             pi[i].push_back(p[i]);

176             pi[i].push_back(p[i+n]);

177             sort(pi[i].begin(),pi[i].end(),cmp);

178             for(j = 0 ; j < pi[i].size()-1 ; j++)

179             {

180                 Point tp;

181                 Point p1 = pi[i][j],p2= pi[i][j+1];

182                 if(dcmp(p1.x-p2.x)==0&&dcmp(p1.y-p2.y)==0) continue;

183                 tp.x = (p1.x+p2.x)/2;

184                 tp.y = (p1.y+p2.y)/2;

185                 // printf("%d tpx = %.2f tpy = %.2f p1x = %.2f p1y = %.2f p2x = %.2f p2y = %.2f\n",i,tp.x,tp.y,p1.x,p1.y,p2.x,p2.y);

186                 q[++g] = tp;

187             }

188             pi[i].clear();

189         }

190         g++;

191         scanf("%lf%lf",&q[g].x,&q[g].y);

192         for(i = 1; i <= g ; i++)

193             ed[i].clear();

194         for(i = 1; i <= g ; i++)

195         {

196             //  printf("%.2f %.2f\n",q[i].x,q[i].y);

197             for(j = 1; j <= g ; j++)

198             {

199                 if(i==j) continue;

200                 for(e = 1; e <= n; e++)

201                 {

202                     if(seginter(q[i],q[j],p[e],p[e+n]))

203                     {

204 //                        if(i==g)

205 //                        printf("%.2f %.2f e = %d\n",q[j].x,q[j].y,e);

206                         break;

207                     }

208                 }

209                 if(e>n)

210                 {

211 //                    if(i==g)

212 //                    printf("%.2f %.2f %.2f %.2f\n",q[i].x,q[i].y,q[j].x,q[j].y);

213                     ed[i].push_back(j);

214                 }

215             }

216         }

217         bfs(g);

218 //    }

219     return 0;

220 }
View Code

感觉这题没那么复杂,交对后搜了下题解,,然后 这题是一个水题,确实水。。

因为这个点的最终目的是要走出去的,边界上墙的点相对于边界上其它的点应该是更优的,所以只需枚举这些点到达起点经过多少堵墙即可。

几何抓不住重点是件很纠结的事。

附优美的简短的跑得飞快的代码

 1 #include <iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<algorithm>

 5 #include<stdlib.h>

 6 #include<vector>

 7 #include<cmath>

 8 #include<queue>

 9 #include<set>

10 using namespace std;

11 #define N 2210

12 #define LL long long

13 #define INF 0xfffffff

14 const double eps = 1e-10;

15 const double inf = ~0u>>2;

16 vector<int>ed[N];

17 struct Point

18 {

19     double x,y;

20     Point(double x=0,double y=0):x(x),y(y) {} //构造函数 方便代码编写

21 } p[105],q[N];

22 int g,dis[N];

23 bool vis[N];

24 vector<Point>pi[N];

25 typedef Point pointt;

26 pointt operator + (Point a,Point b)

27 {

28     return Point(a.x+b.x,a.y+b.y);

29 }

30 pointt operator - (Point a,Point b)

31 {

32     return Point(a.x-b.x,a.y-b.y);

33 }

34 pointt operator * (Point a,double b)

35 {

36     return Point(a.x*b,a.y*b);

37 }

38 pointt operator / (Point a,double b)

39 {

40     return Point(a.x/b,a.y/b);

41 }

42 bool operator < (const Point &a,const Point &b)

43 {

44     return a.x<b.x||(a.x==b.x&&a.y<b.y);

45 }

46 int dcmp(double x)

47 {

48     if(fabs(x)<eps) return 0;

49     else return x<0?-1:1;

50 }

51 double cross(Point a,Point b)

52 {

53     return a.x*b.y-a.y*b.x;

54 }

55 bool seginter(pointt a1,pointt a2,pointt b1,pointt b2)

56 {

57     double c1 = cross(a2-a1,b1-a1),c2 = cross(a2-a1,b2-a1),

58                                         c3 = cross(b2-b1,a1-b1),c4 = cross(b2-b1,a2-b1);

59     return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;

60 }

61 int main()

62 {

63     int n,i,j,e;

64     scanf("%d",&n);

65     g = 0;

66     for(i = 1; i <= n ; i++)

67     {

68         scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i+n].x,&p[i+n].y);

69     }

70     Point tp;

71     scanf("%lf%lf",&tp.x,&tp.y);

72     if(n==0)

73     {

74         puts("Number of doors = 1");

75         return 0;

76     }

77     int ans = INF;

78     for(i = 1 ; i <= n*2; i++)

79     {

80         int ts = 1;

81         for(j = 1 ; j <= n ; j++)

82         {

83             if(seginter(p[i],tp,p[j],p[j+n]))

84                 ts++;

85         }

86         ans = min(ans,ts);

87     }

88     printf("Number of doors = %d\n",ans);

89     return 0;

90 }
View Code

 

你可能感兴趣的:(poj)