Language: C++

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );

template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

#include <complex>
#include <cmath>
#define EPS 1.0e-10
#define INF 1.0e5
#define PI 3.1415926535897932384 

// テ・ツョツ淌ヲツ閉ーテ」ツ?ョテァツャツヲテ・ツ渉キテゥツ鳴「テヲツ閉ー
inline int signum(double x) { return (abs(x) < EPS ? 0 : x > 0 ? 1 : -1); }
//XYテ・ツコツァテヲツィツ?
#define X real()
#define Y imag()
// テァツつケ
typedef complex<double> P;
 

// テァツキツ堙・ツ按?」ツδサテ・ツ債甘ァツ崢エテァツキツ堙」ツδサテァツ崢エテァツキツ?
struct L { P pos, dir; L(P p=P(), P d=P()):pos(p),dir(d){}};

// テ・ツ、ツ堙ィツァツ津・ツスツ「
typedef vector<P> G;
 
// テ・ツ??
struct C { P p; double r; };

// std::norm テ」ツ?ッabs(p)*abs(p)テ」ツ?ェテ」ツ?ョテ」ツ?ァテゥツ??」ツ??
inline double norm(P p){
	return p.X*p.X+p.Y*p.Y;
}

// テ、ツコツ古」ツ?、テ」ツ?ョテ」ツδ凖」ツつッテ」ツδ暗」ツδォテ」ツ?ョテ・ツ??ァツゥツ催」ツつ津ィツィツ暗ァツョツ療」ツ?凖」ツつ?
inline double inp(const P& a, const P& b) {
	return (conj(a)*b).real();
}
 
// テ、ツコツ古」ツ?、テ」ツ?ョテ」ツδ凖」ツつッテ」ツδ暗」ツδォテ」ツ?ョテ・ツ、ツ姪ァツゥツ催」ツつ津ィツィツ暗ァツョツ療」ツ?凖」ツつ?
inline double outp(const P& a, const P& b) {
	return (conj(a)*b).imag();
}

inline int ccw(const P& p, const P& r, const P& s) {
    P a(r-p), b(s-p);
    int sgn = signum(outp(a, b));
    if (sgn != 0)
        return sgn;
    if (a.real()*b.real() < -EPS || a.imag()*b.imag() < -EPS)
        return -1;
    if (norm(a) < norm(b) - EPS)
        return 1;
    return 0;
}

bool sp_intersects(const L& s, const P& p) {
    return ( abs(s.pos - p) + abs(s.pos + s.dir - p) - abs(s.dir) < EPS );
}
bool insideP(G& g, const P& p) {
	if(ccw(g[0], g[1], g[2]) != 1) swap(g[1], g[2]);
	if(norm(g[0]-p) < EPS || norm(g[1]-p) < EPS || norm(g[2]-p) < EPS) return false;
    double sum = 0.0;
    int n = g.size();
    if(n && g[0] == p) return false;
    for(int i = 0; i < n; i++) {
        int j = (i+1)%n;
        if (sp_intersects(L(g[i], g[j]-g[i]), p))
            return true;
        sum += arg((g[j]-p)/(g[i]-p));
    }
    return (abs(sum) > 1);
}

bool xy_less(const P& a, const P& b) {
    if (abs(a.imag()-b.imag()) < EPS) return (a.real() < b.real());
    return (a.imag() < b.imag());
}
template<class IN>
void walk_rightside(IN begin, IN end, vector<P>& v) {
    IN cur = begin;
    v.push_back(*cur++);
    vector<P>::size_type s = v.size();
    v.push_back(*cur++);
    while(cur != end) {
        if (v.size() == s || ccw(v[v.size()-2], v.back(), *cur) > EPS)
            v.push_back(*cur++);
        else
            v.pop_back();
    }
    v.pop_back();
}
//テ・ツ?クテ・ツ個?」ツつ津ヲツアツづ」ツつ?」ツつ?
vector<P> convex_hull(vector<P> v) {
    if (v.size() <= 1)
        return v; // EXCEPTIONAL
    sort(v.begin(), v.end(), xy_less);
    vector<P> cv;
    walk_rightside(v.begin(), v.end(), cv);
    walk_rightside(v.rbegin(), v.rend(), cv);
    return cv;
}

int n;
P S, T;

double dfs(P S1, P S2, vector<P> p, double l){
//	cout << "(" << S1 << ", " << S2  << ", " << l << ") start" << endl;
	G g, g2;
	g.push_back(S1);
	g.push_back(S2);
	g.push_back(T);
	g2.push_back(S1);
	g2.push_back(T);
	REP(i, p.size()) if(insideP(g, p[i])) g2.push_back(p[i]);
	g2 = convex_hull(g2);
	double sum = 0;
	if(g2.size() == 2 && abs(T-S1) < l+EPS){
//		cout << "3(" << S1 << ", " << S2  << ", " << l << ") = " << abs(S2-T) << endl << endl;
		return abs(S2-T);
	}
	REP(i, g2.size()) sum += abs(g2[i]-g2[(i+1)%g2.size()]);
	if(sum - abs(T-S1) < l+EPS){
//		cout << "2(" << S1 << ", " << S2  << ", " << l << ") = " << abs(S2-T) << endl << endl;
		return abs(S2-T);
	}
	double res = INF;
	REP(i, p.size()){
		if(norm(p[i]-S2) < EPS || !insideP(g, p[i])) continue;
//		cout << "!" << p[i] << endl;
		G g, g2;
		g.push_back(S1);
		g.push_back(S2);
		g.push_back(p[i]);
		g2.push_back(S1);
		g2.push_back(p[i]);
		REP(j, p.size()) if(i!=j && insideP(g, p[j])) g2.push_back(p[j]);
		g2 = convex_hull(g2);
//		cout << g2 << endl;
		double sum = 0;
		if(g2.size() == 2 && abs(p[i]-S1) < l+EPS) chmin(res, abs(S2-p[i]) + dfs(S1, p[i], p, l));
		REP(j, g2.size()) sum += abs(g2[j]-g2[(j+1)%g2.size()]);
		
		if(sum - abs(p[i]-S1) < l+EPS){
			P prev;
			REP(j, g2.size()) if(abs(g2[j]-p[i])<EPS) prev = g2[(j+g2.size()-1)%g2.size()];
//			cout << g2 << endl;
//			cout << "prev is " << prev << endl;
//			cout << "dfs" << prev << "," << p[i] << endl;
			chmin(res, abs(S2-p[i]) + dfs(prev, p[i], p, l-(sum - abs(p[i]-S1) - abs(p[i]-prev))));
		}
	}
//	cout << "1(" << S1 << ", " << S2 << ", " << l << ") = " << res << endl << endl;
	return res;
}

main(){
	while(cin >> n, n){
		vector<P> p;
		cin >> S.X >> S.Y >> T.X >> T.Y;
		REP(i, n){
			double x, y;
			cin >> x >> y;
			p.push_back(P(x, y));
		}
		if(ccw(P(0, 0), S, T) == -1){
			REP(i, n) p[i].Y = -p[i].Y;
			S.Y = -S.Y;
			T.Y = -T.Y;
		}
		double ret = dfs(P(0, 0), S, p, abs(S));
		if(ret > 90000) puts("-1");
		else printf("%.9f\n", ret);
	}
	return 0;
}

Compiler output:
a.cc:202:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
  202 | main(){
      | ^~~~
a.cc: In function 'int main()':
a.cc:205:21: error: no match for 'operator>>' (operand types are 'std::istream' {aka 'std::basic_istream<char>'} and 'double')
  205 |                 cin >> S.X >> S.Y >> T.X >> T.Y;
      |                 ~~~ ^~
      |                 |
      |                 std::istream {aka std::basic_istream<char>}
In file included from /usr/include/c++/14/iostream:42,
                 from a.cc:14:
/usr/include/c++/14/istream:170:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(bool&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  170 |       operator>>(bool& __n)
      |       ^~~~~~~~
/usr/include/c++/14/istream:170:7: note:   conversion of argument 1 would be ill-formed:
a.cc:60:15: error: cannot bind non-const lvalue reference of type 'bool&' to a value of type 'double'
   60 | #define X real()
      |               ^
a.cc:205:26: note: in expansion of macro 'X'
  205 |                 cin >> S.X >> S.Y >> T.X >> T.Y;
      |                          ^
/usr/include/c++/14/istream:174:7: note: candidate: 'std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(short int&) [with _CharT = char; _Traits = std::char_traits<char>]' (near match)
  174 |       operator>>(short& __n);
      |       ^~~~~~~~
/usr/include/c++/14/istream:174:7: note:   conversion of argument 1 would be ill-formed:
a.cc:60:15: error: cannot bind non-const lvalue reference of type 'short int&' to a value of type 'double'
   60 | #define X real()
      |               ^
a.cc:205:26: note: in expansion of macro 'X'
  205 |                 cin >> S.X >> S.Y >> T.X >> T.Y;
      |                          ^
/usr/include/c++/14/istream:177:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(short unsigned int&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  177 |       operator>>(unsigned short& __n)
      |       ^~~~~~~~
/usr/include/c++/14/istream:177:7: note:   conversion of argument 1 would be ill-formed:
a.cc:60:15: error: cannot bind non-const lvalue reference of type 'short unsigned int&' to a value of type 'double'
   60 | #define X real()
      |               ^
a.cc:205:26: note: in expansion of macro 'X'
  205 |                 cin >> S.X >> S.Y >> T.X >> T.Y;
      |                          ^
/usr/include/c++/14/istream:181:7: note: candidate: 'std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(int&) [with _CharT = char; _Traits = std::char_traits<char>]' (near match)
  181 |       operator>>(int& __n);
      |       ^~~~~~~~
/usr/include/c++/14/istream:181:7: note:   conversion of argument 1 would be ill-formed:
a.cc:60:15: error: cannot bind non-const lvalue reference of type 'int&' to a value of type 'double'
   60 | #define X real()
      |               ^
a.cc:205:26: note: in expansion of macro 'X'
  205 |                 cin >> S.X >> S.Y >> T.X >> T.Y;
      |                          ^
/usr/include/c++/14/istream:184:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(unsigned int&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  184 |       operator>>(unsigned int& __n)
      |       ^~~~~~~~
/usr/include/c++/14/istream:184:7: note:   conversion of argument 1 would be ill-formed:
a.cc:60:15: error: cannot bind non-const lvalue reference of type 'unsigned int&' to a value of type 'double'
   60 | #define X real()
      |               ^
a.cc:205:26: note: in expansion of macro 'X'
  205 |                 cin >> S.X >> S.Y >> T.X >> T.Y;
      |                          ^
/usr/include/c++/14/istream:188:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long int&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  188 |       operator>>(long& __n)
      |       ^~~~~~~~
/usr/include/c++/14/istream:188:7: note:   conversion of argument 1 would be ill-formed:
a.cc:60:15: error: cannot bind non-const lvalue reference of type 'long int&' to a value of type 'double'
   60 | #define X real()
      |               ^
a.cc:205:26: note: in expansion of macro 'X'
  205 |                 cin >> S.X >> S.Y >> T.X >> T.Y;
      |                          ^
/usr/include/c++/14/istream:192:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long unsigned int&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  192 |       operator>>(unsigned long& __n)
      |       ^~~~~~~~
/usr/include/c++/14/istream:192:7: note:   conversion of argument 1 would be ill-formed:
a.cc:60:15: error: cannot bind non-const lvalue reference of type 'long unsigned int&' to a value of type 'double'
   60 | #define X real()
      |               ^
a.cc:205:26: note: in expansion of macro 'X'
  205 |                 cin >> S.X >> S.Y >> T.X >> T.Y;
      |                          ^
/usr/include/c++/14/istream:199:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long long int&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  199 |       operator>>(long long& __n)
      |       ^~~~~~~~
/usr/include/c++/14/istream:199:7: note:   conversion of argument 1 would be ill-formed:
a.cc:60:15: error: cannot bind non-const lvalue reference of type 'long long int&' to a value of type 'double'
   60 | #define X real()
      |               ^
a.cc:205:26: note: in expansion of macro 'X'
  205 |                 cin >> S.X >> S.Y >> T.X >> T.Y;
      |                          ^
/usr/include/c++/14/istream:203:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long long unsigned int&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  203 |       operator>>(unsigned long long& __n)
      |       ^~~~~~~~
/usr/include/c++/14/istream:203:7: note:   conversion of argument 1 would be ill-formed:
a.cc:60:15: error: cannot bind non-const lvalue reference of type 'long long unsigned int&' to a value of type 'double'
   60 | #define X real()
      |               ^
a.cc:205:26: note: in expansion of macro 'X'
  205 |                 cin >> S.X >> S.Y >> T.X >> T.Y;
      |                          ^
/usr/include/c++/14/istream:219:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(float&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  219 |       operator>>(float& __f)
      |       ^~~~~~~~
/usr/include/c++/14/istream:219:7: note:   conversion of argument 1 would be ill-formed:
a.cc:60:15: error: cannot bind non-const lvalue reference of type 'float&' to a value of type 'double'
   60 | #define X real()
      |               ^
a.cc:205:26: note: in expansion of macro 'X'
  205 |                 cin >> S.X >> S.Y >> T.X >> T.Y;
      |                          ^
/usr/include/c++/14/istream:223:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(double&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  223 |       operator>>(double& __f)
      |       ^~~~~~~~
/usr/include/c++/14/istream:223:7: note:   conversion of argument 1 would be ill-formed:
a.cc:60:15: error: cannot bind non-const lvalue reference of type 'double&' to an rvalue of type 'double'
   60 | #define X real()
      |               ^
a.cc:205:26: note: in expansion of macro 'X'
  205 |                 cin >> S.X >> S.Y >> T.X >> T.Y;
      |                          ^
/usr/include/c++/14/istream:227:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long double&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  227 |       operator>>(long double& __f)
      |       ^~~~~~~~
/usr/include/c++/14/istream:227:7: note:   conversion of argument 1 would be ill-formed:
a.cc:60:15: error: cannot bind non-const lvalue reference of type 'long double&' to a value of type 'double'
   60 | #define X real()
      |               ^
a.cc:205:26: note: in expansion of macro 'X'
  205 |                 cin >> S.X >> S.Y >> T.X >> T.Y;
      |                          ^
/usr/include/c++/14/istream:328:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(void*&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]'
  328 |       operator>>(void*& __p)
      |       ^~~~~~~~
/usr/include/c++/14/istream:328:25: note:   no known conversion for argument 1 from 'double' to 'void*&'
  328 |       operator>>(void*& __p)
      |                  ~~~~~~~^~~
/usr/include/c++/14/istream:122:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(__istream_type& (*)(__istream_type&)) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]'
  122 |       operator>>(__istream_type& (*__pf)(__istream_type&))
      |       ^~~~~~~~
/usr/include/c++/14/istream:122:36: note:   no known conversion for argument 1 from 'double' to 'std::basic_istream<char>::__istream_type& (*)(std::basic_istream<char>::__istream_type&)' {aka 'std::basic_ist