Run Time: 0.000
Ranking (as of 2016-05-25): 59 out of 521
Language: C++
/*
UVa 393 - The Doors
To build using Visual Studio 2012:
cl -EHsc -O2 UVa_393_The_Doors.cpp
ACM Mid-Central Regionals 1996, Problem #2
(http://www.ntnu.edu.tw/acm/ProblemSetArchive/B_US_MidCen/1996/index.html)
*/
#include <algorithm>
#include <limits>
#include <cstdio>
#include <cmath>
using namespace std;
const double infinite = numeric_limits<double>::max(),
epsilon = numeric_limits<double>::epsilon();
const int nr_walls_max = 18, nr_ys = 4;
struct wall {
double x_;
double ys_[nr_ys];
} walls[nr_walls_max + 2] = {
// walls[0] is the chamber's left wall and
// walls[nr_walls_max + 1] is the chamber's right wall
{0.0, {5.0, 5.0, 5.0, 5.0}}
};
int nr_walls;
double distances[nr_walls_max + 2][nr_ys][nr_walls_max + 2][nr_ys];
// distances[si][sj][ei][ej] is the distance between walls[si].ys_[sj]
// and walls[ei].ys_[ej]
double get_distance(int si, int sj, int ei, int ej)
{
double dx = walls[ei].x_ - walls[si].x_, dy = walls[ei].ys_[ej] - walls[si].ys_[sj],
dm = dy / dx;
for (int i = si + 1; i < ei; i++) {
double y = walls[si].ys_[sj] + dm * (walls[i].x_ - walls[si].x_);
if (y >= walls[i].ys_[0] - epsilon && y <= walls[i].ys_[1] + epsilon ||
y >= walls[i].ys_[2] - epsilon && y <= walls[i].ys_[3] + epsilon)
;
else
return infinite;
}
return sqrt(dx * dx + dy * dy);
}
int main()
{
while (true) {
scanf("%d", &nr_walls);
if (nr_walls == -1)
break;
for (int i = 1; i <= nr_walls; i++) {
wall& w = walls[i];
scanf("%lf %lf %lf %lf %lf", &w.x_, &w.ys_[0], &w.ys_[1], &w.ys_[2], &w.ys_[3]);
}
nr_walls++;
walls[nr_walls].x_ = 10.0;
walls[nr_walls].ys_[0] = walls[nr_walls].ys_[1] =
walls[nr_walls].ys_[2] = walls[nr_walls].ys_[3] = 5.0;
for (int si = 0; si <= nr_walls; si++)
for (int sj = 0; sj < nr_ys; sj++)
for (int ei = 0; ei <= nr_walls; ei++)
for (int ej = 0; ej < nr_ys; ej++)
distances[si][sj][ei][ej] = (ei > si) ? get_distance(si, sj, ei, ej) : infinite;
for (int mi = 1; mi <= nr_walls; mi++)
for (int mj = 0; mj < nr_ys; mj++)
for (int ei = 1; ei <= nr_walls; ei++)
for (int ej = 0; ej < nr_ys; ej++)
if (distances[0][0][mi][mj] < infinite &&
distances[mi][mj][ei][ej] < infinite)
distances[0][0][ei][ej] = min(distances[0][0][ei][ej],
distances[0][0][mi][mj] + distances[mi][mj][ei][ej]);
printf("%.2lf\n", distances[0][0][nr_walls][0]);
}
return 0;
}
No comments:
Post a Comment