Language: C++

#include <bits/stdc++.h>
using namespace std;


const double EPS = 1e-10, PI = acos(-1);
   
inline bool eq(double a,double b){ return abs(b - a) < EPS; }
#define curr(P,i) P[i]
#define next(P,i) P[(i+1)%P.size()]
#define prev(P,i) P[(i+P.size()-1) % P.size()]
enum { OUT, ON, IN };
namespace Geometory
{
  struct Point {
    double x, y;
    Point(){};
    Point(double x,double y):x(x),y(y){};
    Point operator+(const Point& b) const { return Point(x + b.x,y + b.y); }
    Point operator-(const Point& b) const { return Point(x - b.x,y - b.y); }
    Point operator*(const double b) const { return Point(x * b,y * b); }
    Point operator*(const Point& b) const { return Point(x * b.x - y * b.y,x * b.y + y * b.x); }
    Point operator/(const double b) const { return Point(x / b,y / b); }
    bool operator< (const Point& b) const { return x != b.x ? x < b.x : y < b.y;}
    bool operator==(const Point& b) const { return eq(x,b.x) && eq(y,b.y); }
    double norm(){ return x * x + y * y; }
    double arg(){ return atan2(x,y); }
    double abs(){ return sqrt(norm()); }
    Point rotate(double theta){ return Point(cos(theta) * x - sin(theta) * y,sin(theta) * x + cos(theta) * y); }
    Point rotate90(){ return Point(-y,x); }
    friend ostream& operator<<(ostream& os, Point& p){ return os<<"("<<p.x<<","<<p.y<<")"; }
    friend istream& operator>>(istream& is, Point& a){ return is>>a.x>>a.y; }
  };
      
  struct Line {
    Point a, b;
    Line(){};
    Line(Point a,Point b):a(a),b(b){};
    friend ostream& operator<<(ostream& os, Line& p){ return os<<"("<<p.a.x<<","<<p.a.y<<") to ("<<p.b.x<<","<<p.b.y<<")"; }
    friend istream& operator>>(istream& is, Line& a){ return is>>a.a.x>>a.a.y>>a.b.x>>a.b.y; }
  };
  struct Segment {
    Point a, b;
    Segment(){};
    Segment(Point a,Point b):a(a),b(b){};
    friend ostream& operator<<(ostream& os, Segment& p){ return os<<"("<<p.a.x<<","<<p.a.y<<") to ("<<p.b.x<<","<<p.b.y<<")"; }
    friend istream& operator>>(istream& is, Segment& a){ return is>>a.a.x>>a.a.y>>a.b.x>>a.b.y; }
  };
  struct Circle {
    Point p; double r;
    Circle(){};
    Circle(Point p, double r) : p(p),r(r){};
  };
  typedef vector< Point > Polygon;
  typedef vector< Segment > Segments;
  typedef vector< Line > Lines;
  typedef vector< Circle > Circles;
  typedef pair< Point, Point > PointPoint;
      
  double cross(const Point& a,const Point& b){
    return a.x * b.y - a.y * b.x;
  }
  double dot(const Point& a,const Point& b){
    return a.x * b.x + a.y * b.y;
  }
      
  int ccw(const Point& a,Point b,Point c){
    b = b - a, c = c - a;
    if(cross(b,c) > EPS)    return +1;  // a    b         v     ??      c
    if(cross(b,c) < -EPS)    return -1; // a    b       v     ??      c
    if(dot(b,c) < 0)      return +2;  // c -- a -- b ?????    
    if(b.norm() < c.norm()) return -2; // a -- b -- c ?????    
    return 0;  // a -- c -- b ?????    
  }
  Point Projection(const Line& l, const Point& p){
    double t = dot(p - l.a, l.a - l.b) / (l.a - l.b).norm();
    return l.a + (l.a - l.b) * t;
  }
  Point Projection(const Segment& l, const Point& p){
    double t = dot(p - l.a, l.a - l.b) / (l.a - l.b).norm();
    return l.a + (l.a - l.b) * t;
  }
  Point Reflection(const Line& l, const Point& p){
    return p + (Projection(l, p) - p) * 2.0;
  }
      
  double Distance(const Line& l,const Point& p) { //OK
    return (p - Projection(l, p)).abs();
  }
      
  bool Intersect(const Line& l, const Line& m){
    return abs(cross(l.b - l.a, m.b - m.a)) > EPS || abs(cross(l.b-l.a, m.b-l.a)) < EPS;
  }
  bool Intersect(const Line& l, const Segment& s){
    return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < EPS;
  }
  bool Intersect(const Line& l, const Point& p){
    return abs(ccw(l.a, l.b, p)) != -1;
  }
  bool Intersect(const Segment& s, const Segment& t){
    return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
  }
  bool Intersect(const Segment& s, const Point& p){
    return ccw(s.a, s.b, p) == 0;
  }
  bool Intersect(const Circle& c,const Line& l){
    return Distance(l, c.p) <= c.r + EPS;
  }
  bool Intersect(const Circle& c,const Point& p){
    return abs((p - c.p).abs() - c.r ) < EPS;
  }
  int Intersect(const Circle& c, const Segment& l){
    if((Projection(l, c.p) - c.p).norm() - c.r * c.r > EPS) return 0;
    const double d1 = (c.p - l.a).abs(), d2 = (c.p - l.b).abs();
    if(d1 < c.r + EPS && d2 < c.r + EPS) return 0;
    if(d1 < c.r - EPS && d2 > c.r + EPS || d1 > c.r + EPS && d2 < c.r - EPS ) return 1;
    const Point h = Projection(l, c.p);
    if(dot(l.a - h, l.b - h) < 0) return 2;
    return 0;
  }
  bool Intersect(const Circle& a,const Circle& b){
    return ((a.p - b.p).norm() - (a.r + b.r) * (a.r + b.r) < EPS) &&
      ((a.p - b.p).norm() - (a.r - b.r) * (a.r - b.r) > -EPS);
  }
  double Distance(const Segment& s,const Point& p){
    Point r = Projection(s, p);
    if (Intersect(s, r)) return (r - p).abs();
    return min((s.a - p).abs(), (s.b - p).abs());
  }
  double Distance(const Segment& a,const Segment& b){
    if(Intersect(a, b)) return 0;
    return min(min(Distance(a, b.a), Distance(a, b.b)), min(Distance(b, a.a), Distance(b, a.b)));
  }
  double Distance(const Line& l,const Line& m) {
    return Intersect(l, m) ? 0 : Distance(l, m.a);
  }
  double Distance(const Line& l,const Segment& s) { //OK
    if (Intersect(l, s)) return 0;
    return min(Distance(l, s.a), Distance(l, s.b));
  }
  double Distance(const Point& a,const Point& b){ //OK
    return (a - b).abs();
  }
  Point Crosspoint(const Segment& l,const Segment& m) { //OK
    double A = cross(l.b - l.a, m.b - m.a);
    double B = cross(l.b - l.a, l.b - m.a);
    if (abs(A) < EPS && abs(B) < EPS) return m.a; // same line
    return m.a + (m.b - m.a) * B / A;
  }
  PointPoint Crosspoint(const Circle& c,const Line l){
    Point hp = Projection(l, c.p), h =  hp - c.p;
    const double d2 = h.norm();
    Point v = (l.b - l.a) * sqrt(c.r * c.r - d2) / (l.b - l.a).abs();
    return PointPoint(hp - v, hp + v);
  }
  PointPoint Crosspoint(const Circle& c,const Segment& l) {
    Line aa = Line(l.a, l.b);
    if(Intersect(c, l) == 2) return Crosspoint(c, aa);
    PointPoint ret = Crosspoint(c, aa);
    if(dot(l.a - ret.first, l.b - ret.first) < 0) ret.second = ret.first;
    else ret.first = ret.second;
    return ret;
  }
  PointPoint Crosspoint(const Circle& c1,const Circle& c2){ //OK
    double d = (c1.p - c2.p).abs();
    double s = (c1.r + c2.r + d) / 2;
    double S = sqrt(s * (s - c1.r) * (s - c2.r) * (s - d));
    double h = 2 * S / d;
    Point v = (c2.p - c1.p) / (c2.p - c1.p).abs();
    double m = sqrt(c1.r * c1.r - h * h);
    return PointPoint(c1.p + v * m + Point(0,1) * h * v, c1.p + v * m - Point(0,1) * h * v);
  }
  bool parallel(const Line& a,const Line& b){
    return abs(cross(a.b - a.a, b.b - b.a)) < EPS;
  }
  bool orthogonal(const Line& a,const Line& b){
    return abs(dot(a.a - a.b, b.a - b.b)) < EPS;
  }
  int Contains(const Polygon& Q,const Point& p){
    bool in = false;
    for(int i = 0 ; i < Q.size() ; i++ ){
      Point a = curr(Q,i) - p, b = next(Q,i) - p;
      if(a.y > b.y) swap(a,b);
      if(a.y <= 0 && 0 < b.y && cross(a,b) < 0) in = !in;
      if(cross(a,b) == 0 && dot(a,b) <= 0) return ON;
    }
    return in ? IN : OUT;
  }
  bool Contains(const Circle& c,const Point& p){
    return (c.p - p).abs() < c.r + EPS;
  }
  double Area2(const Polygon& p){ //OK
    double A = 0;
    for (int i = 0; i < p.size(); ++i){
      A += cross(curr(p, i), next(p, i));
    }
    return A;
  }
  bool IsConvex(const Polygon& p){
    for(int i = 0; i < p.size(); i++){
      if(ccw(prev(p,i), curr(p,i), next(p,i)) == -1) return false;
    }
    return true;
  }
  Polygon Convex_Hull(Polygon& p){
    int n = p.size(), k = 0;
    if(n >= 3){
      sort(p.begin(), p.end());
      vector< Point > ch(2 * n);
      for(int i = 0; i < n; ch[k++] = p[i++]){
        while(k >= 2 && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) --k;
      }
      for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]){
        while(k >= t && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) --k;
      }
      ch.resize(k - 1);
      return ch;
    } else {
      return p;
    }
  }
  double Convex_Diameter(Polygon& p){
    int n = p.size();
    int is = 0, js = 0;
    for(int i = 1; i < n; i++){
      if(p[i].y > p[is].y) is = i;
      if(p[i].y < p[js].y) js = i;
    }
    double maxdis = (p[is] - p[js]).norm();
    
    int maxi, maxj, i, j;
    i = maxi = is;
    j = maxj = js;
    do {
      if(cross(next(p, i) - curr(p, i), next(p, j) - curr(p, j)) >= 0){
        j = (j + 1) % n;
      } else {
        i = (i + 1) % n;
      }
      if((p[i] - p[j]).norm() > maxdis){
        maxdis = (p[i] - p[j]).norm();
        maxi = i; maxj = j;
      }
    }  while (i != is || j != js);
    return maxdis;
  }
};


using namespace Geometory;
int main()
{
  int N;
  while(cin >> N, N) {
    vector< Segment > Segments(N);
    int ret = 0;
    for(int i = 0; i < N; i++) {
      cin >> Segments[i];
      vector< Point > ps;
      for(int j = i - 1; j >= 0; j--) {
        if(Intersect(Segments[i], Segments[j])) {
          Point p = Crosspoint(Segments[i], Segments[j]);
          if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
        }
      }
      sort(ps.begin(), ps.end());
      ps.erase(unique(ps.begin(), ps.end()), ps.end());
      ret += ps.size() + 1; 
    }
    cout << ret + 1 << endl;
  }
}

Compiler output:
a.cc: In function 'int main()':
a.cc:262:16: error: no match for 'operator!=' (operand types are 'Geometory::Point' and 'Geometory::Point')
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |              ~ ^~
      |              |
      |              Geometory::Point
In file included from /usr/include/c++/14/regex:68,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:181,
                 from a.cc:1:
/usr/include/c++/14/bits/regex.h:1132:5: note: candidate: 'template<class _BiIter> bool std::__cxx11::operator!=(const sub_match<_BiIter>&, const sub_match<_BiIter>&)'
 1132 |     operator!=(const sub_match<_BiIter>& __lhs, const sub_match<_BiIter>& __rhs)
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1132:5: note:   template argument deduction/substitution failed:
a.cc:262:31: note:   'Geometory::Point' is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |                               ^
/usr/include/c++/14/bits/regex.h:1212:5: note: candidate: 'template<class _Bi_iter, class _Ch_traits, class _Ch_alloc> bool std::__cxx11::operator!=(__sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>&, const sub_match<_BiIter>&)'
 1212 |     operator!=(const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1212:5: note:   template argument deduction/substitution failed:
a.cc:262:31: note:   'Geometory::Point' is not derived from 'std::__cxx11::__sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>'
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |                               ^
/usr/include/c++/14/bits/regex.h:1305:5: note: candidate: 'template<class _Bi_iter, class _Ch_traits, class _Ch_alloc> bool std::__cxx11::operator!=(const sub_match<_BiIter>&, __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>&)'
 1305 |     operator!=(const sub_match<_Bi_iter>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1305:5: note:   template argument deduction/substitution failed:
a.cc:262:31: note:   'Geometory::Point' is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |                               ^
/usr/include/c++/14/bits/regex.h:1379:5: note: candidate: 'template<class _Bi_iter> bool std::__cxx11::operator!=(const typename std::iterator_traits<_Iter>::value_type*, const sub_match<_BiIter>&)'
 1379 |     operator!=(typename iterator_traits<_Bi_iter>::value_type const* __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1379:5: note:   template argument deduction/substitution failed:
a.cc:262:31: note:   'Geometory::Point' is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |                               ^
/usr/include/c++/14/bits/regex.h:1473:5: note: candidate: 'template<class _Bi_iter> bool std::__cxx11::operator!=(const sub_match<_BiIter>&, const typename std::iterator_traits<_Iter>::value_type*)'
 1473 |     operator!=(const sub_match<_Bi_iter>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1473:5: note:   template argument deduction/substitution failed:
a.cc:262:31: note:   'Geometory::Point' is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |                               ^
/usr/include/c++/14/bits/regex.h:1547:5: note: candidate: 'template<class _Bi_iter> bool std::__cxx11::operator!=(const typename std::iterator_traits<_Iter>::value_type&, const sub_match<_BiIter>&)'
 1547 |     operator!=(typename iterator_traits<_Bi_iter>::value_type const& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1547:5: note:   template argument deduction/substitution failed:
a.cc:262:31: note:   'Geometory::Point' is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |                               ^
/usr/include/c++/14/bits/regex.h:1647:5: note: candidate: 'template<class _Bi_iter> bool std::__cxx11::operator!=(const sub_match<_BiIter>&, const typename std::iterator_traits<_Iter>::value_type&)'
 1647 |     operator!=(const sub_match<_Bi_iter>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1647:5: note:   template argument deduction/substitution failed:
a.cc:262:31: note:   'Geometory::Point' is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |                               ^
/usr/include/c++/14/bits/regex.h:2213:5: note: candidate: 'template<class _Bi_iter, class _Alloc> bool std::__cxx11::operator!=(const match_results<_BiIter, _Alloc>&, const match_results<_BiIter, _Alloc>&)'
 2213 |     operator!=(const match_results<_Bi_iter, _Alloc>& __m1,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:2213:5: note:   template argument deduction/substitution failed:
a.cc:262:31: note:   'Geometory::Point' is not derived from 'const std::__cxx11::match_results<_BiIter, _Alloc>'
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |                               ^
In file included from /usr/include/c++/14/bits/stl_algobase.h:64,
                 from /usr/include/c++/14/algorithm:60,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:51:
/usr/include/c++/14/bits/stl_pair.h:1052:5: note: candidate: 'template<class _T1, class _T2> constexpr bool std::operator!=(const pair<_T1, _T2>&, const pair<_T1, _T2>&)'
 1052 |     operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_pair.h:1052:5: note:   template argument deduction/substitution failed:
a.cc:262:31: note:   'Geometory::Point' is not derived from 'const std::pair<_T1, _T2>'
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |                               ^
In file included from /usr/include/c++/14/bits/stl_algobase.h:67:
/usr/include/c++/14/bits/stl_iterator.h:455:5: note: candidate: 'template<class _Iterator> constexpr bool std::operator!=(const reverse_iterator<_Iterator>&, const reverse_iterator<_Iterator>&)'
  455 |     operator!=(const reverse_iterator<_Iterator>& __x,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:455:5: note:   template argument deduction/substitution failed:
a.cc:262:31: note:   'Geometory::Point' is not derived from 'const std::reverse_iterator<_Iterator>'
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |                               ^
/usr/include/c++/14/bits/stl_iterator.h:500:5: note: candidate: 'template<class _IteratorL, class _IteratorR> constexpr bool std::operator!=(const reverse_iterator<_Iterator>&, const reverse_iterator<_IteratorR>&)'
  500 |     operator!=(const reverse_iterator<_IteratorL>& __x,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:500:5: note:   template argument deduction/substitution failed:
a.cc:262:31: note:   'Geometory::Point' is not derived from 'const std::reverse_iterator<_Iterator>'
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |                               ^
/usr/include/c++/14/bits/stl_iterator.h:1686:5: note: candidate: 'template<class _IteratorL, class _IteratorR> constexpr bool std::operator!=(const move_iterator<_IteratorL>&, const move_iterator<_IteratorR>&)'
 1686 |     operator!=(const move_iterator<_IteratorL>& __x,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:1686:5: note:   template argument deduction/substitution failed:
a.cc:262:31: note:   'Geometory::Point' is not derived from 'const std::move_iterator<_IteratorL>'
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |                               ^
/usr/include/c++/14/bits/stl_iterator.h:1753:5: note: candidate: 'template<class _Iterator> constexpr bool std::operator!=(const move_iterator<_IteratorL>&, const move_iterator<_IteratorL>&)'
 1753 |     operator!=(const move_iterator<_Iterator>& __x,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:1753:5: note:   template argument deduction/substitution failed:
a.cc:262:31: note:   'Geometory::Point' is not derived from 'const std::move_iterator<_IteratorL>'
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |                               ^
In file included from /usr/include/c++/14/bits/char_traits.h:42,
                 from /usr/include/c++/14/string:42,
                 from /usr/include/c++/14/bitset:52,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:52:
/usr/include/c++/14/bits/postypes.h:197:5: note: candidate: 'template<class _StateT> bool std::operator!=(const fpos<_StateT>&, const fpos<_StateT>&)'
  197 |     operator!=(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs)
      |     ^~~~~~~~
/usr/include/c++/14/bits/postypes.h:197:5: note:   template argument deduction/substitution failed:
a.cc:262:31: note:   'Geometory::Point' is not derived from 'const std::fpos<_StateT>'
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |                               ^
In file included from /usr/include/c++/14/string:43:
/usr/include/c++/14/bits/allocator.h:243:5: note: candidate: 'template<class _T1, class _T2> bool std::operator!=(const allocator<_CharT>&, const allocator<_T2>&)'
  243 |     operator!=(const allocator<_T1>&, const allocator<_T2>&)
      |     ^~~~~~~~
/usr/include/c++/14/bits/allocator.h:243:5: note:   template argument deduction/substitution failed:
a.cc:262:31: note:   'Geometory::Point' is not derived from 'const std::allocator<_CharT>'
  262 |           if(p != Segments[i].a && p != Segments[i].b) ps.push_back(p);
      |                               ^
In file included from /usr/include/c++/14/bits/basic_string.h:47,
                 fro