Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- using namespace std;
- double eps = 1e-8;
- double ans;
- double INF = 1e11;
- struct Point
- {
- double x, y;
- Point () {}
- Point (double a, double b) : x(a), y(b) {}
- void Scan()
- {
- scanf("%lf%lf", &x, &y);
- }
- void Print()
- {
- printf("%.3lf %.3lf\n", x, y);
- }
- Point operator + (Point a)
- {
- return Point(x + a.x, y + a.y);
- }
- Point operator - (Point a)
- {
- return Point(x - a.x, y - a.y);
- }
- double operator % (Point a)
- {
- return x * a.x + y * a.y;
- }
- double operator * (Point a)
- {
- return x * a.y - y * a.x;
- }
- Point operator * (double a)
- {
- return Point(x * a, y * a);
- }
- double len()
- {
- return sqrt(x * x + y * y);
- }
- };
- Point A, B, C, S, T;
- Point O;
- bool intersect(Point P, Point a, Point Q, Point b)
- {
- if (fabs(a * b) < eps)
- return false;
- double m = ((P - Q) * a) / (b * a);
- O = Q + b * m;
- return true;
- }
- bool isOnSegment(Point Q, Point W, Point Z)
- {
- if (((Q - W) % (Z - W) > eps) && ((Q - Z) % (W - Z) > eps))
- return true;
- return false;
- }
- bool inter(Point Y, Point U, Point I, Point P)
- {
- if (!intersect(Y, U - Y, I, P - I))
- return false;
- if (isOnSegment(O, Y, U) && isOnSegment(O, I, P))
- return true;
- return false;
- }
- int main()
- {
- // freopen("input.txt", "r", stdin);
- // freopen("output.txt", "w", stdout);
- int w;
- scanf("%d", &w);
- for (int i = 0; i < w; i++)
- {
- S.Scan();
- T.Scan();
- A.Scan();
- B.Scan();
- C.Scan();
- ans = INF;
- //напрямую
- if (!inter(S, T, A, B) && !inter(S, T, B, C))
- if (ans > (S - T).len())
- ans = (S - T).len();
- //через одну из граничных
- if (!inter(S, A, B, C) && !inter(A, T, B, C))
- if (ans > (S - A).len() + (A - T).len())
- ans = (S - A).len() + (A - T).len();
- if (!inter(S, C, B, A) && !inter(C, T, B, A))
- if (ans > (S - C).len() + (C - T).len())
- ans = (S - C).len() + (C - T).len();
- //через центр и одну из граничных
- if (ans > (S - B).len() + (B - A).len() + (A - T).len())
- ans = (S - B).len() + (B - A).len() + (A - T).len();
- if (ans > (S - B).len() + (B - C).len() + (C - T).len())
- ans = (S - B).len() + (B - C).len() + (C - T).len();
- if (ans > (T - B).len() + (B - A).len() + (A - S).len())
- ans = (T - B).len() + (B - A).len() + (A - S).len();
- if (ans > (T - B).len() + (B - C).len() + (C - S).len())
- ans = (T - B).len() + (B - C).len() + (C - S).len();
- //через две граничных
- if (!inter(S, C, B, A) && !inter(A, T, B, C))
- if (ans > (S - C).len() + (C - A).len() + (A - T).len())
- ans = (S - C).len() + (C - A).len() + (A - T).len();
- if (!inter(S, A, B, C) && !inter(C, T, B, C))
- if (ans > (S - A).len() + (A - C).len() + (C - T).len())
- ans = (S - A).len() + (A - C).len() + (C - T).len();
- double PI = 4. * atan(1.);
- double alpha = atan2((A - B) * (S - B), (A - B) % (S - B)), beta = atan2((A - B) * (T - B), (A - B) % (T - B)), gamma = atan2((A - B) * (C - B), (A - B) % (C - B));
- if (alpha < 0)
- alpha += 2 * PI;
- if (beta < 0)
- beta += 2 * PI;
- if (gamma < 0)
- gamma += 2 * PI;
- //через центр
- if ((alpha - gamma) * (beta - gamma) > 0)
- if (ans > (S - B).len() + (B - T).len())
- ans = (S - B).len() + (B - T).len();
- printf("%.8lf\n", ans);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment