Problem A: Railway
Problem A: Railway |
Problem
Railway is a broken line of N segments. The problem is to find sucha position for the railway station that the distance from it to thegiven pointM is the minimal.
Input
The input will consist of several input blocks.Each input block begins with two lines with coordinatesXm and Ymof the point M. In the third line there is N - the number ofbroken line segments. The next 2N+2 lines contain theX and the Ycoordinates of consecutive broken line corners.
The input is terminated by <EOF>.
Output
For each input block there should be two output lines. The first one contains the first coordinate of the station position, the second one contains the second coordinate.Coordinates are the floating-point values with four digits after decimal point.
Sample Input
6-3301559-51530011020
Sample Output
7.8966-2.24141.00000.0000
#include <cstdio>
#include <climits>
using namespace std;
const double EPS = 1e-6;
struct Point
{
double x, y;
Point(double x = 0.0, double y = 0.0):x(x), y(y) {}
Point operator + (const Point &other)
{
return Point(x + other.x, y + other.y);
}
Point operator - (const Point &other)
{
return Point(x - other.x, y - other.y);
}
Point operator * (double d)
{
return Point(x * d, y * d);
}
Point operator / (double d)
{
return Point(x / d, y / d);
}
double dot(const Point &other)
{
return x * other.x + y * other.y;
}
double cross(const Point &other)
{
return x * other.y - y * other.x;
}
};
double mindis;
Point ans;
inline bool onsegment(Point &a, Point &b, Point &c);
inline Point intersection(Point &a, Point &b, Point &c, Point d);
void solve(Point &a, Point &b, Point &m);
int main()
{
#ifndef ONLINE_JUDGE
freopen("d:\\OJ\\uva_in.txt", "r", stdin);
#endif
Point p1, p2, m;
int n;
while (scanf("%lf%lf", &m.x, &m.y) == 2) {
scanf("%d", &n);
scanf("%lf%lf", &p2.x, &p2.y);
mindis = INT_MAX;
while (n--) {
p1 = p2;
scanf("%lf%lf", &p2.x, &p2.y);
solve(p1, p2, m);
}
printf("%.4lf\n%.4lf\n", ans.x, ans.y);
}
return 0;
}
void solve(Point &a, Point &b, Point &m)
{
Point p = intersection(a, b, m, m + Point(a.y - b.y, b.x - a.x));
if (!onsegment(a, b, p)) {
if ((b - a).dot(p - a) > EPS) p = b;
else p = a;
}
double dis = (p - m).dot(p - m);
if (dis + EPS < mindis) {
mindis = dis;
ans = p;
}
}
Point intersection(Point &a, Point &b, Point &c, Point d)
{
return a + (b - a) * ((d - c).cross(c - a) / (d - c).cross(b - a));
}
bool onsegment(Point &a, Point &b, Point &c)
{
return (a - c).dot(b - c) < EPS;
}