Advertisement
Guest User

Untitled

a guest
May 6th, 2016
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.02 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <set>
  4. #include <map>
  5. #include <string>
  6. #include <cmath>
  7. #include <queue>
  8. #include <fstream>
  9.  
  10. using namespace std;
  11.  
  12. const long double INF = 1e9;
  13. const long double EPS = 1 / INF;
  14.  
  15. bool eq(long double a, long double b) {
  16.     return abs(a - b) < EPS;
  17. }
  18.  
  19. struct Point {
  20.     long double x, y;
  21.     Point() {}
  22.     Point(long double x_, long double y_) : x(x_), y(y_) {}
  23. };
  24.  
  25. const Point UNDEFINED = Point(1e100, 1e100);
  26.  
  27. bool operator> (const Point& a, const Point& b) {
  28.     return a.x > b.x || a.x == a.x && a.y > a.y;
  29. }
  30.  
  31. bool operator== (const Point& a, const Point& b) {
  32.     return eq(a.x, b.x) && eq(a.y, b.y);
  33. }
  34.  
  35. bool operator!= (const Point &a, const Point& b) {
  36.     return !(a == b);
  37. }
  38.  
  39. istream& operator>> (istream& is, Point& p) {
  40.     is >> p.x >> p.y;
  41.     return is;
  42. }
  43.  
  44. ostream& operator<< (ostream& os, Point& p) {
  45.     return os << p.x << ' ' << p.y;
  46. }
  47.  
  48. ifstream& operator >> (ifstream& is, Point& p) {
  49.     is >> p.x >> p.y;
  50.     return is;
  51. }
  52.  
  53. ofstream& operator<< (ofstream& os, Point& p) {
  54.     os << p.x << ' ' << p.y << ' ';
  55.     return os;
  56. }
  57.  
  58. long double distance(const Point& a, const Point& b) {
  59.     return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
  60. }
  61.  
  62. class Line {
  63. public:
  64.     long double k, b, x;
  65.     bool upr;
  66. public:
  67.     Line() {}
  68.     Line(Point fir, Point sec) {
  69.         if (fir > sec) {
  70.             swap(fir, sec);
  71.         }
  72.         long double dy = sec.y - fir.y;
  73.         long double dx = sec.x - fir.x;
  74.         if (eq(dx, 0)) {
  75.             upr = true;
  76.             x = fir.x;
  77.         }
  78.         else {
  79.             upr = false;
  80.             k = dy / dx;
  81.             b = fir.y - k * fir.x;
  82.         }
  83.     }
  84.     bool contain(Point p) {
  85.         return upr ? eq(p.x, x): eq(k * p.x + b, p.y);
  86.     }
  87.     bool parallelTo(const Line line) {
  88.         return upr ? line.upr : k == line.k;
  89.     }
  90.     bool operator==(const Line& line2) {
  91.         if (!parallelTo(line2)) {
  92.             return 0;
  93.         }
  94.         return upr ? line2.x == x : b == line2.b;
  95.     }
  96. };
  97.  
  98. bool parallel(const Line l1, const Line l2) {
  99.     if (l1.upr || l2.upr) {
  100.         return l1.upr && l2.upr;
  101.     }
  102.     return l1.k == l2.k;
  103. }
  104.  
  105. class Segment {
  106. public:
  107.     Point a, b;
  108.     Line line;
  109. public:
  110.     Segment(Point fir, Point sec) : a(fir), b(sec) {
  111.         line = Line(a, b);
  112.     }
  113.     long double length() {
  114.         return distance(a, b);
  115.     }
  116.     Point middle() {
  117.         return Point((a.x + b.x) / 2, (a.y + b.y) / 2);
  118.     }
  119.     bool contains(Point p) {
  120.         long double lx = min(a.x, b.x);
  121.         long double rx = max(a.x, b.x);
  122.         long double ly = min(a.y, b.y);
  123.         long double ry = max(a.y, b.y);
  124.         return line.contain(p) && lx - EPS < p.x && p.x < rx + EPS && ly - EPS < p.y && p.y < ry + EPS;
  125.     }
  126.     bool contains_inside(Point p) {
  127.         return contains(p) && p != a && p != b;
  128.     }
  129. };
  130.  
  131. Point intersect(Line line1, Line line2) {
  132.     if (parallel(line1, line2)) {
  133.         return UNDEFINED;
  134.     }
  135.     if (line2.upr) {
  136.         swap(line1, line2);
  137.     }
  138.     if (line1.upr) {
  139.         return Point(line1.x, line1.x * line2.k + line2.b);
  140.     }
  141.     long double x = (line2.b - line1.b) / (line1.k - line2.k);
  142.     long double y = x * line1.k + line1.b;
  143.     return Point(x, y);
  144. }
  145.  
  146. Point intersect(Segment& a, Segment& b) {
  147.     Point lines_intersection = intersect(a.line, b.line);
  148.     return a.contains(lines_intersection) && b.contains(lines_intersection) ? lines_intersection : UNDEFINED;
  149. }
  150.  
  151. bool intersectedStrict(Segment& a, Segment& b) {
  152.     Point p = intersect(a, b);
  153.     return p != a.a && p != a.b && p != b.a && p != b.b;
  154. }
  155.  
  156. long double solve(Point S, Point T, Point A, Point B, Point C) {
  157.     Segment st(S, T), sa(S, A), sb(S, B), sc(S, C), at(A, T), bt(B, T), ct(C, T), ab(A, B), bc(B, C), ac(A, C);
  158.     vector<vector<long double> > a(5, vector<long double> (5, INF));
  159.     for (int i = 0; i < 5; i++) {
  160.         a[i][i] = 0;
  161.     }
  162.     a[0][2] = sb.length();
  163.     Point sa_bc = intersect(sa, bc);
  164.     if (!bc.contains_inside(sa_bc)) {
  165.         a[0][1] = sa.length();
  166.     }
  167.     Point sc_ab = intersect(sc, ab);
  168.     if (!ab.contains_inside(sc_ab)) {
  169.         a[0][3] = sc.length();
  170.     }
  171.     a[0][2] = sb.length();
  172.     a[1][2] = a[2][1] = ab.length();
  173.     a[2][3] = a[3][2] = bc.length();
  174.     a[1][3] = a[3][1] = ac.length();
  175.     a[2][4] = bt.length();
  176.     if (!bc.contains_inside(intersect(at, bc))) {
  177.         a[1][4] = at.length();
  178.     }
  179.     if (!ab.contains_inside(intersect(ct, ab))) {
  180.         a[3][4] = ct.length();
  181.     }
  182.     Point p1, p2;
  183.     p1 = intersect(st, ab);
  184.     p2 = intersect(st, bc);
  185.     if (!ab.contains_inside(p1) && !bc.contains_inside(p2) && (!st.contains(B) || !ac.contains(intersect(st.line, ac.line)))) {
  186.         a[0][4] = st.length();
  187.     }
  188.     long double ans = INF;
  189.     for (int v1 = 1; v1 < 5; v1++) {
  190.         if (v1 != 2) {
  191.             ans = min(ans, a[0][v1] + a[v1][4]);
  192.         }
  193.         if (v1 == 2 && !ac.contains_inside(intersect(sb.line, ac.line)) && !ac.contains_inside(intersect(bt.line, ac.line))) {
  194.             ans = min(ans, a[0][v1] + a[v1][4]);
  195.         }
  196.     }
  197.     for (int v1 = 1; v1 < 4; v1++) {
  198.         for (int v2 = 1; v2 < 4; v2++) {
  199.             if (v1 != v2) {
  200.                 ans = min(ans, a[0][v1] + a[v1][v2] + a[v2][4]);
  201.             }
  202.         }
  203.     }
  204.     return ans;
  205. }
  206.  
  207. int main() {
  208.     cout << fixed;
  209.     cout.precision(10);
  210.     int n;
  211.     cin >> n;
  212.     for (int i = 0; i < n; i++) {
  213.         Point S, T, A, B, C;
  214.         cin >> S >> T >> A >> B >> C;
  215.         cout << solve(S, T, A, B, C) << '\n';
  216.     }
  217.     system("pause");
  218.     return 0;
  219. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement