Language: C++

#include <iostream>
#include <algorithm>
#include <complex>
#include <vector>

using namespace std;

typedef complex<double> Point;

struct Segment{ Point p1, p2; };

const double EPS = 1e-2;
const double INF = 1e5;

bool equals(double a, double b){
  return abs(a-b) < EPS;
}

double dot(Point a, Point b){
  return real(conj(a) * b);
}

double cross(Point a, Point b){
  return imag(conj(a) * b);
}

Point project(Segment s, Point p){
  Point base = s.p2 - s.p1;
  double t = dot(p - s.p1, base) / norm(base);
  return s.p1 + base * t;
}

Point reflect(Segment s, Point p){
  return p + (project(s, p) - p) * 2.0;
}

int ccw(Point p0, Point p1, Point p2){
  Point a = p1 - p0;
  Point b = p2 - p0;
  if(cross(a, b) > EPS) return 1;
  if(cross(a, b) < -EPS) return -1;
  if(dot(a, b) < -EPS) return 2;
  if(norm(a) < norm(b)) return -2;
  return 0;
}

bool isIntersect(Point p1, Point p2, Point p3, Point p4){
  return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
          ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0);
}

bool isIntersect(Segment s1, Segment s2){
  return isIntersect(s1.p1, s1.p2, s2.p1, s2.p2);
}

Point getCrossPoint(Segment s1, Segment s2){
  Point base = s2.p2 - s2.p1;
  double d1 = abs(cross(base, s1.p1 - s2.p1));
  double d2 = abs(cross(base, s1.p2 - s2.p1));
  double t = d1 / (d1 + d2);
  return s1.p1 + (s1.p2 - s1.p1) * t;
}

double getDistance(Point a, Point b){
  return abs(a - b);
}

vector<Point> targets;
vector<Segment> mirrors;
int n;

double calc(Point s, Point t, Point d){
  double res = 0.0;
  Point cur = s;
  Point dir = d;
  for(int k=0;k<6;k++){
    int id = -1;
    double valm = INF;
    dir = cur + (dir - cur) * INF;
    Segment seg = (Segment){cur, dir};
    Point c;
    for(int i=0;i<mirrors.size();i++){
      if(ccw(mirrors[i].p1, mirrors[i].p2, cur) == 0) continue;
      if(//!equals(abs(cross(dir-cur, mirrors[i].p2-mirrors[i].p1)), 0.0) &&
         isIntersect(seg, mirrors[i]) &&
         ccw(cur, dir, mirrors[i].p1) != 0 &&
         ccw(cur, dir, mirrors[i].p2) != 0){
        double tmp = getDistance(cur, getCrossPoint(seg, mirrors[i]));
        if(equals(tmp, 0.0)) continue;
        if(valm > tmp + EPS){
          valm = tmp;
          id = i;
          c = getCrossPoint(seg, mirrors[i]);
        }
      }
    }
    if(ccw(cur, dir, t) == 0){
      double tmp = getDistance(cur, t);
      if(valm > tmp + EPS) return res + tmp;
    }
    if(id == -1) break;
    if(k < 5){
      res += valm;
      Point vec = mirrors[id].p2 - mirrors[id].p1;
      Point nor(-vec.imag(), vec.real());
      dir = reflect((Segment){c+nor, c}, cur);
      cur = c;
    }
  }
  return INF;
}

void init(){
  targets.clear();
  mirrors.clear();
}

main(){
  while(cin >> n && n){
    init();
    for(int i=0;i<n;i++){
      Segment in;
      cin >> in.p1.real() >> in.p1.imag();
      cin >> in.p2.real() >> in.p2.imag();
      mirrors.push_back(in);
    }
    Point s, t;
    cin >> t.real() >> t.imag();
    cin >> s.real() >> s.imag();
    targets.push_back(t);
    for(int i=0;i<5;i++){
      int size = targets.size();
      for(int j=0;j<size;j++){
        for(int k=0;k<n;k++){
          targets.push_back(reflect(mirrors[k], targets[j]));
        }
      }
    }
    double ans = INF;
    for(int i=0;i<targets.size();i++){
      ans = min(ans, calc(s, t, targets[i]));
    }
    printf("%.14f\n", ans);
  }
}

Compiler output:
a.cc:118:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
  118 | main(){
      | ^~~~
a.cc: In function 'int main()':
a.cc:123:11: error: no match for 'operator>>' (operand types are 'std::istream' {aka 'std::basic_istream<char>'} and 'double')
  123 |       cin >> in.p1.real() >> in.p1.imag();
      |       ~~~ ^~ ~~~~~~~~~~~~
      |       |                |
      |       |                double
      |       std::istream {aka std::basic_istream<char>}
In file included from /usr/include/c++/14/iostream:42,
                 from a.cc:1:
/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:123:24: error: cannot bind non-const lvalue reference of type 'bool&' to a value of type 'double'
  123 |       cin >> in.p1.real() >> in.p1.imag();
      |              ~~~~~~~~~~^~
/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:123:24: error: cannot bind non-const lvalue reference of type 'short int&' to a value of type 'double'
  123 |       cin >> in.p1.real() >> in.p1.imag();
      |              ~~~~~~~~~~^~
/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:123:24: error: cannot bind non-const lvalue reference of type 'short unsigned int&' to a value of type 'double'
  123 |       cin >> in.p1.real() >> in.p1.imag();
      |              ~~~~~~~~~~^~
/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:123:24: error: cannot bind non-const lvalue reference of type 'int&' to a value of type 'double'
  123 |       cin >> in.p1.real() >> in.p1.imag();
      |              ~~~~~~~~~~^~
/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:123:24: error: cannot bind non-const lvalue reference of type 'unsigned int&' to a value of type 'double'
  123 |       cin >> in.p1.real() >> in.p1.imag();
      |              ~~~~~~~~~~^~
/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:123:24: error: cannot bind non-const lvalue reference of type 'long int&' to a value of type 'double'
  123 |       cin >> in.p1.real() >> in.p1.imag();
      |              ~~~~~~~~~~^~
/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:123:24: error: cannot bind non-const lvalue reference of type 'long unsigned int&' to a value of type 'double'
  123 |       cin >> in.p1.real() >> in.p1.imag();
      |              ~~~~~~~~~~^~
/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:123:24: error: cannot bind non-const lvalue reference of type 'long long int&' to a value of type 'double'
  123 |       cin >> in.p1.real() >> in.p1.imag();
      |              ~~~~~~~~~~^~
/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:123:24: error: cannot bind non-const lvalue reference of type 'long long unsigned int&' to a value of type 'double'
  123 |       cin >> in.p1.real() >> in.p1.imag();
      |              ~~~~~~~~~~^~
/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:123:24: error: cannot bind non-const lvalue reference of type 'float&' to a value of type 'double'
  123 |       cin >> in.p1.real() >> in.p1.imag();
      |              ~~~~~~~~~~^~
/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:123:24: error: cannot bind non-const lvalue reference of type 'double&' to an rvalue of type 'double'
  123 |       cin >> in.p1.real() >> in.p1.imag();
      |              ~~~~~~~~~~^~
/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:123:24: error: cannot bind non-const lvalue reference of type 'long double&' to a value of type 'double'
  123 |       cin >> in.p1.real() >> in.p1.imag();
      |              ~~~~~~~~~~^~
/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_istream<char>& (*)(std::basic_istream<char>&)'}
  122 |       operator>>(__istream_type& (*__pf)(__istream_type&))
      |                  ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/14/istream:126:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(__ios_type& (*)(__ios_type&)) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>; __ios_type = std::basic_ios<char>]'
  126 |       operator>>(__ios_type& (*__pf)(__ios_type&))
      |       ^~~~~~~~
/usr/include/c++/14/istream:126:32: note:   no known conversion for argument 1 from 'double' to 'std::basic_istream<char>::__ios_type& (*)(std::basic_istream<char>::__ios_type&)' {aka 'std::basic_ios<char>& (*)(std::basic_ios<char>&)'}
  126 |       operator>>(__ios_type& (*__pf)(__ios_type&))
      |                  ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
/usr/include/c++/14/istream:133:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::ios_base& (*)(std::ios_base&)) [with _CharT = char; _Traits = std::char_traits<