Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <set>
- #include <map>
- #include <string>
- #include <cmath>
- #include <queue>
- #include <fstream>
- using namespace std;
- const long double INF = 1e9;
- const long double EPS = 1 / INF;
- bool eq(long double a, long double b) {
- return abs(a - b) < EPS;
- }
- struct Point {
- long double x, y;
- Point() {}
- Point(long double x_, long double y_) : x(x_), y(y_) {}
- };
- const Point UNDEFINED = Point(1e100, 1e100);
- bool operator> (const Point& a, const Point& b) {
- return a.x > b.x || a.x == a.x && a.y > a.y;
- }
- bool operator== (const Point& a, const Point& b) {
- return eq(a.x, b.x) && eq(a.y, b.y);
- }
- bool operator!= (const Point &a, const Point& b) {
- return !(a == b);
- }
- istream& operator>> (istream& is, Point& p) {
- is >> p.x >> p.y;
- return is;
- }
- ostream& operator<< (ostream& os, Point& p) {
- return os << p.x << ' ' << p.y;
- }
- ifstream& operator >> (ifstream& is, Point& p) {
- is >> p.x >> p.y;
- return is;
- }
- ofstream& operator<< (ofstream& os, Point& p) {
- os << p.x << ' ' << p.y << ' ';
- return os;
- }
- long double distance(const Point& a, const Point& b) {
- return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
- }
- class Line {
- public:
- long double k, b, x;
- bool upr;
- public:
- Line() {}
- Line(Point fir, Point sec) {
- if (fir > sec) {
- swap(fir, sec);
- }
- long double dy = sec.y - fir.y;
- long double dx = sec.x - fir.x;
- if (eq(dx, 0)) {
- upr = true;
- x = fir.x;
- }
- else {
- upr = false;
- k = dy / dx;
- b = fir.y - k * fir.x;
- }
- }
- bool contain(Point p) {
- return upr ? eq(p.x, x): eq(k * p.x + b, p.y);
- }
- bool parallelTo(const Line line) {
- return upr ? line.upr : k == line.k;
- }
- bool operator==(const Line& line2) {
- if (!parallelTo(line2)) {
- return 0;
- }
- return upr ? line2.x == x : b == line2.b;
- }
- };
- bool parallel(const Line l1, const Line l2) {
- if (l1.upr || l2.upr) {
- return l1.upr && l2.upr;
- }
- return l1.k == l2.k;
- }
- class Segment {
- public:
- Point a, b;
- Line line;
- public:
- Segment(Point fir, Point sec) : a(fir), b(sec) {
- line = Line(a, b);
- }
- long double length() {
- return distance(a, b);
- }
- Point middle() {
- return Point((a.x + b.x) / 2, (a.y + b.y) / 2);
- }
- bool contains(Point p) {
- long double lx = min(a.x, b.x);
- long double rx = max(a.x, b.x);
- long double ly = min(a.y, b.y);
- long double ry = max(a.y, b.y);
- return line.contain(p) && lx - EPS < p.x && p.x < rx + EPS && ly - EPS < p.y && p.y < ry + EPS;
- }
- bool contains_inside(Point p) {
- return contains(p) && p != a && p != b;
- }
- };
- Point intersect(Line line1, Line line2) {
- if (parallel(line1, line2)) {
- return UNDEFINED;
- }
- if (line2.upr) {
- swap(line1, line2);
- }
- if (line1.upr) {
- return Point(line1.x, line1.x * line2.k + line2.b);
- }
- long double x = (line2.b - line1.b) / (line1.k - line2.k);
- long double y = x * line1.k + line1.b;
- return Point(x, y);
- }
- Point intersect(Segment& a, Segment& b) {
- Point lines_intersection = intersect(a.line, b.line);
- return a.contains(lines_intersection) && b.contains(lines_intersection) ? lines_intersection : UNDEFINED;
- }
- bool intersectedStrict(Segment& a, Segment& b) {
- Point p = intersect(a, b);
- return p != a.a && p != a.b && p != b.a && p != b.b;
- }
- long double solve(Point S, Point T, Point A, Point B, Point C) {
- 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);
- vector<vector<long double> > a(5, vector<long double> (5, INF));
- for (int i = 0; i < 5; i++) {
- a[i][i] = 0;
- }
- a[0][2] = sb.length();
- Point sa_bc = intersect(sa, bc);
- if (!bc.contains_inside(sa_bc)) {
- a[0][1] = sa.length();
- }
- Point sc_ab = intersect(sc, ab);
- if (!ab.contains_inside(sc_ab)) {
- a[0][3] = sc.length();
- }
- a[0][2] = sb.length();
- a[1][2] = a[2][1] = ab.length();
- a[2][3] = a[3][2] = bc.length();
- a[1][3] = a[3][1] = ac.length();
- a[2][4] = bt.length();
- if (!bc.contains_inside(intersect(at, bc))) {
- a[1][4] = at.length();
- }
- if (!ab.contains_inside(intersect(ct, ab))) {
- a[3][4] = ct.length();
- }
- Point p1, p2;
- p1 = intersect(st, ab);
- p2 = intersect(st, bc);
- if (!ab.contains_inside(p1) && !bc.contains_inside(p2) && (!st.contains(B) || !ac.contains(intersect(st.line, ac.line)))) {
- a[0][4] = st.length();
- }
- long double ans = INF;
- for (int v1 = 1; v1 < 5; v1++) {
- if (v1 != 2) {
- ans = min(ans, a[0][v1] + a[v1][4]);
- }
- if (v1 == 2 && !ac.contains_inside(intersect(sb.line, ac.line)) && !ac.contains_inside(intersect(bt.line, ac.line))) {
- ans = min(ans, a[0][v1] + a[v1][4]);
- }
- }
- for (int v1 = 1; v1 < 4; v1++) {
- for (int v2 = 1; v2 < 4; v2++) {
- if (v1 != v2) {
- ans = min(ans, a[0][v1] + a[v1][v2] + a[v2][4]);
- }
- }
- }
- return ans;
- }
- int main() {
- cout << fixed;
- cout.precision(10);
- int n;
- cin >> n;
- for (int i = 0; i < n; i++) {
- Point S, T, A, B, C;
- cin >> S >> T >> A >> B >> C;
- cout << solve(S, T, A, B, C) << '\n';
- }
- system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement