【解题报告】 POJ 1556 The Doors -- 最短路问题 Dijkstra算法 + 直线相交
2012-09-05 23:15
323 查看
题目连接:POJ 1556
题目大意:从房间的坐标(0,5) -> (10,5),中间经过最多不超过18个墙,求路径最短。
这道题在nyoj上AC不了,貌似数据中墙会重复输入 ( waiting... )
题目大意:从房间的坐标(0,5) -> (10,5),中间经过最多不超过18个墙,求路径最短。
这道题在nyoj上AC不了,貌似数据中墙会重复输入 ( waiting... )
// POJ 1556 The Doors -- 最短路问题 Dijkstra算法 + 直线相交 // PS : 自我感觉Dijkstra算法类似于 BFS // /*test data 2 4 2 7 8 9 7 3 4.5 6 7 1 5 4 6 7 8 5 4 0 1 2 3 4.5 0 0.5 0.8 1 5 4 6 7 8 7 2 4.6 5 6 9 1.5 2.5 5.5 7.5 -1 =14.56 10.06 10.00 */ #include <stdio.h> #include <math.h> #include <algorithm> using namespace std; const double infiniteS = 0.000001; const int infinite = (1<<30); // 无穷大 const int MAXP = 200; //74 struct POINT{ double x,y; }p[MAXP]; double d[MAXP]; int n; double Abs(double a){ return (a>=0)?(a):(-a); } bool comp(POINT A,POINT B){ // 按 x 排序 if (Abs(A.x - B.x) < infiniteS) return A.y < B.y; else return A.x < B.x; } double Distance(double x1,double y1,double x2,double y2){ return sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) ); } double XJ(POINT p0,POINT p1, POINT p2,POINT p3){ // 一般情况下计算 p0 p1 X p2 p3 的叉积 // (p1.x-p0.x, p1.y-p0.y) vector|p0p1| // (p3.x-p2.x, p3.y-p2.y) vector|p2p3| double res = (p1.x-p0.x)*(p2.y-p0.y) - (p3.x-p2.x)*(p3.y-p2.y); return res; } int XJ(POINT p0,POINT p1, POINT p2){ // p0 p1 p2 顺时针 为正输出1 ,否则-1 ,一条直线上为0 // p0 p1 -> p0 p2 // (p1.x-p0.x, p1.y-p0.y) vector|p0p1| // (p2.x-p0.x, p2.y-p0.y) vector|p0p2| double res = (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y); return (res > infiniteS)?(1):(-1); } bool Segment(POINT a, POINT b, POINT c, POINT d){ // 说明是 1^-1=-2, 存在两个跨立则判定为线段相交 return ((XJ(a,b,c)^XJ(a,b,d))==-2) && ((XJ(a,c,d)^XJ(b,c,d))==-2); } bool ExisTobstacle(int p1,int p2){ // 判断两个点之间有障碍 double left_x = p[p1].x, right_x = p[p2].x; for (int i = p1 + 1; i < p2; i++){ if (Abs(p[i].x - left_x) <= infiniteS)continue; if (Abs(p[i].x - right_x) <= infiniteS)break; POINT a,b; // a i i+1 i+2 i+3 b a.y = 0; b.y = 10; a.x = b.x = p[i].x; if (Segment(a, p[i], p[p1], p[p2]) || Segment(p[i+1], p[i+2], p[p1], p[p2]) || Segment(p[i+3], b, p[p1], p[p2]) ){ // 只要与墙有交点 则存在障碍 return true; } i+=3; } return false; } double Dijkstra(int np){ // (0,5) -> (10,5) 的最短路 for (int i = 0; i < np; i++){ for (int j = i + 1; j < np; j++){ if (p[i].x == p[j].x || ExisTobstacle(i,j) ) continue; double dis = Distance(p[i].x,p[i].y,p[j].x,p[j].y); if (dis + d[i] < d[j]){ d[j] = dis + d[i]; } } } return d[np-1]; } int init(int n){ for (int i = 0; i < MAXP;i++){ d[i] = infinite; } d[0]=0; p[0].x=0;p[0].y=5; int psub=1; for (int i = 0; i < n; i++){ // p[]: 0 1 2 3 4 5 6 7 .... double tempx; scanf("%lf",&tempx); for (int j = 0 ; j < 4; j++){ scanf("%lf",&p[psub].y); p[psub++].x = tempx; } }p[psub].x = 10; p[psub++].y = 5; return psub; } int main() { // freopen("in.txt","r",stdin); while(scanf("%d",&n), n+1){ if (n==0){ printf("10.00\n");continue; } int psub = init(n); // 初始化 sort(&p[0],&p[n-1],comp); printf("%.2lf\n",Dijkstra(psub)); } return 0; }
相关文章推荐
- 【解题报告】HDU 1874 畅通工程续 -- Dijkstra算法详解 单源点最短路问题
- POJ 1556 The Doors(判断线段相交 && 最短路)
- POJ - 1321 棋盘问题 解题报告
- POJ-1183反正切函数的应用 解题报告(数论) 反正切函数,一个同余问题
- poj 1556 The Doors(线段相交,最短路)
- POJ 1556 - The Doors 线段相交不含端点
- poj 1556 判线段相交+最短路问题
- POJ - 1700 Crossing River解题报告(过河问题的贪心策略)
- POJ 1556 The Doors(线段相交)
- poj 1556 The Doors(最短路+判断线段相交)
- 0-1背包问题,poj 3624 Charm Bracelet动态规划-解题报告,增加最优路径构建
- POJ-2488 A Knight's Journey 解题报告(搜索) 马跳遍棋格的字典序问题
- POJ 1017 装箱问题 解题报告
- HDU - 1556 Color the ball解题报告(树状数组 处理区间问题)
- 【POJ】1556 The Doors 最短路+判断线段相交
- 简单几何(线段相交+最短路) POJ 1556 The Doors
- BNU 7536 && HDU 3425 Coverage (圆与直线相交 )TeamContest - 4—B【解题报告】
- POJ 2811 熄灯问题 解题报告
- poj-1556-The Doors-dij+线段相交
- POJ 1017 装箱问题 解题报告