// Javier Gomez Serrano // // O(n^2) solution for slalom. // DP minimizing the path from the start to each of the endpoints of the gates. // Then, 'meet-in-the-middle' to get the minimum between the sum of the DP and // the straight path starting on any interval and ending at the last gate. #include #include #include #define infinity 1000000000 using namespace std; typedef pair interval; int n; double dist2(double x, double y){ return sqrt(x*x+y*y); } double startx,starty; // Returns the intersection of two intervals. isempty returns false if the intersection is empty interval intersection(interval i, interval j, bool& isempty){ interval k; k.first = max(i.first, j.first); k.second = min(i.second, j.second); if (k.first > k.second) isempty = true; return k; } // Returns the distance between (px,py) and (vx,vy) or -1 if vx is not contained in curr double in_intersection(interval curr_i,double vx, double vy,double px,double py){ if (vx < curr_i.first or vx > curr_i.second) return -1; return dist2(vx-px,vy-py); } // What is the minimum distance from (px,py) to the goal(curr_i,vy) in a straight line? double reach_goal(interval curr_i, double vy, double px, double py){ double distmin = infinity; double d1,d2,d3; d1 = in_intersection(curr_i,curr_i.first,vy,startx,starty); d2 = in_intersection(curr_i,curr_i.second,vy,startx,starty); d3 = in_intersection(curr_i,startx,vy,startx,starty); if (d1 > -0.5) distmin = min(distmin, d1); if (d2 > -0.5) distmin = min(distmin, d2); if (d3 > -0.5) distmin = min(distmin, d3); return distmin; } // Distance between endpoints. -1 if it is not possible to reach it double dist[1000][2][1000][2]; int main(){ cout.setf(ios::fixed); cout.precision(9); while (cin >> n,n){ vector > vx; vector vy; cin >> startx >> starty; for (int i=0;i> c >> a >> b; vx.push_back(make_pair(a,b)); vy.push_back(c); } // Can I reach the i-th endpoint from the start in a straight line? // -1 for not reaching, != -1 with the distance double achieve_start[n][2]; // Can I reach the goal from the i-th endpoint in a straight line? // -1 for not reaching, != -1 with the distance double achieve_goal[n][2]; // Best path from the start to the gate, possibly zigzagging double dp[n][2]; // Initialization for (int i=0;iend for (int i=0;i -0.5) dp[i][j] = achieve_start[i][j]; } // DP: min. distance from the start possibly zigzagging for (int i=0;i -0.5){ dp[i][j] = min(dp[i][j], dp[k][l] + dist[k][l][i][j]); } } } } } // We search over the minimum of the sum start->gate + gate->end for (int i=0;i -0.5){ distmin = min(distmin, achieve_goal[i][j] + dp[i][j]); } } } cout << distmin << endl; } return 0; }