- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- typedef long double ld;
- #define endl "\n"
- #define quick ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
- #define ALL(x) x.begin(),x.end()
- #define SORT(x) sort(ALL(x))
- #define FOR(a,b,c) for(int (a)= (b);(a)<(c);++(a))
- #define REP(a,b) FOR(a,0,b)
- #define mp make_pair
- #define pb push_back
- #define pll pair<ll,ll>
- #define pii pair<int,int>
- #define vl vector<ll>
- #define vi vector<int>
- #define f first
- #define s second
- ll ttt = 1, case_ = 0;
- ll n, m, x, y, c;
- template <class myType>
- void print_arr(myType &arr, ll L, string sep){ REP(i,L) {
- cout << arr[i]; if (i < L-1) cout << sep;
- } cout << endl; return; }
- /*
- Try every triangle.
- If every triangle fails, we try quadrilaterals as follows:
- -find all pairs of points such that the blue star lies on the line connecting them
- -if we can find two such pairs of points, all distinct, not all collinear, then that's an answer
- */
- int sign_(ll a) {
- if (a > 0) return 1;
- if (a < 0) return -1;
- return 0;
- }
- bool pt_inside(pll S, pll A, pll B, pll C)
- {
- ll as_x = S.f-A.f;
- ll as_y = S.s-A.s;
- bool s_ab = (B.f-A.f)*as_y-(B.s-A.s)*as_x > 0;
- if((C.f-A.f)*as_y-(C.s-A.s)*as_x > 0 == s_ab) return 0;
- if((C.f-B.f)*(S.s-B.s)-(C.s-B.s)*(S.f-B.f) > 0 != s_ab) return 0;
- vector<pll> PTS = {A, B, C};
- for (int i = 0; i < 3; i++) {
- for(int j = i+1; j < 3; j++) {
- pll g1, g2;
- g1 = mp(PTS[i].f - S.f, PTS[i].s - S.s);
- g2 = mp(PTS[j].f - S.f, PTS[j].s - S.s);
- if (g1.f < 0) {
- g1.f *= -1;
- g1.s *= -1;
- }
- if (g2.f < 0) {
- g2.f *= -1;
- g2.s *= -1;
- }
- if (g1.f == 0) g1.s = abs(g1.s);
- if (g2.f == 0) g2.s = abs(g2.s);
- ll G1 = __gcd(g1.f, g1.s), G2 = __gcd(g2.f, g2.s);
- g1.f /= G1;
- g1.s /= G1;
- g2.f /= G2;
- g2.s /= G2;
- if (g1 == g2) return 0;
- }
- }
- return 1;
- }
- ld dist(pll a, pll b) {
- ld xx, yy;
- xx = (ld) a.f - (ld) b.f;
- yy = (ld) a.s - (ld) b.s;
- return (ld) sqrtl( xx*xx + yy*yy );
- }
- void solve() {
- case_++;
- cout << "Case #" << case_ << ": ";
- cin >> n;
- vector<pll> pts(n);
- REP(i,n) {
- cin >> pts[i].f >> pts[i].s;
- }
- pll S;
- cin >> S.f >> S.s;
- ld const BIG = (ld) 1e18;
- ld ans = BIG;
- ld eps = 0.01;
- for(int i = 0; i < n; i++) {
- for(int j = i+1; j < n; j++) {
- for(int k = j+1; k < n; k++) {
- if (pt_inside(S, pts[i], pts[j], pts[k])) {
- ans = min(ans, dist(pts[i], pts[j]) + dist(pts[j], pts[k]) + dist(pts[k], pts[i]));
- //cout << pts[i].f << " " << pts[i].s << " " << pts[j].f << " " << pts[j].s << " " << pts[k].f << " " << pts[k].s << ans << endl;
- }
- }
- }
- }
- // calculate the gradient of the line connecting the blue star with the white star
- // store points by gradient
- // for each gradient, if > 1 point and there are points either side of the blue star, then we have a candidate pair
- map<pll, vector<pll>> grads;
- for(int i = 0; i < n; i++) {
- ll dx, dy;
- dx = S.f - pts[i].f;
- dy = S.s - pts[i].s;
- if (dx < 0) {
- dy = -dy;
- dx = -dx;
- }
- ll G = __gcd(abs(dx), abs(dy));
- dx /= G;
- dy /= G;
- if (dx == 0) dy = abs(dy);
- grads[mp(dx, dy)].pb(pts[i]);
- }
- map<pll,vector<pll>>::iterator it = grads.begin();
- // dx is always >= 0
- vector<pair<pll, pll>> cands;
- while (it != grads.end()){
- SORT(it->s);
- vector<pll> p = it->s;
- //cout << it->f.f << " " << it->f.s << endl;
- for(int i = 0; i < p.size() - 1; i++) {
- //cout << p[i].f << " " << p[i].s << " " << p[i+1].f << " " << p[i+1].s << endl;
- if (sign_(p[i].f - S.f) == sign_(S.f - p[i+1].f) && sign_(p[i].s - S.s) == sign_(S.s - p[i+1].s)) {
- cands.pb(mp(p[i], p[i+1]));
- break;
- }
- }
- it++;
- }
- for(int i = 0; i < cands.size(); i++) {
- //cout << cands[i].f.f << " " << cands[i].f.s << " " << cands[i].s.f << " " << cands[i].s.s << endl;
- for(int j = i+1; j < cands.size(); j++) {
- ans = min(ans, dist(cands[i].f, cands[j].f) + dist(cands[i].f, cands[j].s) + dist(cands[i].s, cands[j].f) + dist(cands[i].s, cands[j].s));
- }
- }
- if (abs(ans - (ld) 1e18) < eps) {
- cout << "IMPOSSIBLE" << endl;
- return;
- }
- cout << setprecision(20) << ans << endl;
- return;
- }
- int main(){
- quick;
- cin >> ttt;
- while (ttt--) solve();
- return 0;
- }