Language: C++

#include<iostream>
#include<complex>
#include<algorithm>
#define EPS 1e-10
using namespace std;

typedef complex<double> P;

int n,m;
P p[100][4];

double cross(P a,P b){return imag(conj(a)*b);}
double dot(P a,P b){return real(conj(a)*b);}


bool interp(int q,P x){
  P tmp = P(10000,x.imag());
  bool res = false;
  for(int i=0;i<4;i++)if(is_cp(p[q][i],p[q][(i+1)%4],x,tmp))res=!res;
  return res;
}

int ccw(P a,P b,P c){
  b -= a;c -= a;
  if (cross(b,c)>EPS) return 1;
  if (cross(b,c)<-EPS) return -1;
  if (dot(b, c)<-EPS) return 2;
  if (abs(b)<abs(c)) return -2;
  return 0;
}

bool is_cp(P a1, P a2, P b1, P b2){
    return ( ccw(a1, a2, b1) * ccw(a1, a2, b2) <= 0 &&
     ccw(b1, b2, a1) * ccw(b1, b2, a2) <= 0 );
}
/*
bool interp(int q, P x){
  for(int i=0;i<4;i++){
    if ( ccw(p[q][i], p[q][(i+1)%4], x ) == 1 ) return false;
  }
  return true;
}
*/
bool inter(int q1,int q2){
  for(int i=0;i<4;i++)
    for(int j=0;j<4;j++)
      if(is_cp(p[q1][i],p[q1][(i+1)%4],p[q2][j],p[q2][(j+1)%4]))return true;
  for(int i=0;i<4;i++)if(interp(q1,p[q2][i]))return true;
  for(int i=0;i<4;i++)if(interp(q2,p[q1][i]))return true;
  return false;
}

int par[100];
int rank[100];

void init(int n){
  for(int i=0;i<n;i++){
    par[i] = i;
    rank[i] = 0;
  }
}

int find(int x){
  if(par[x] == x)return x;
  return par[x] = find(par[x]);
}

void unite(int x,int y){
  x = find(x);
  y = find(y);
  if(x==y)return;

  if(rank[x] < rank[y])par[x] = y;
  else{
    par[y] = x;
    if(rank[x] == rank[y])rank[x]++;
  }
}

int main(){
  while(cin >> n && n){
    for(int i=0;i<n;i++){
      cin >> m;
      for(int j=0;j<m;j++)
	for(int k=0;k<4;k++)cin >> p[j][k].real() >> p[j][k].imag();

      init(m);

      for(int j=0;j<m;j++)
	for(int k=0;k<j;k++)
	  for(int l=0;l<4;l++)
	    if(inter(j,k))unite(j,k);

      int ans = 0;
      for(int j=0;j<m;j++){
	find(j);
	if(par[j]==j)ans++;
      }
      cout << ans << endl;
    }
  }
}

Compiler output:
a.cc: In function 'bool interp(int, P)':
a.cc:19:26: error: 'is_cp' was not declared in this scope
   19 |   for(int i=0;i<4;i++)if(is_cp(p[q][i],p[q][(i+1)%4],x,tmp))res=!res;
      |                          ^~~~~
a.cc: In function 'void init(int)':
a.cc:59:5: error: reference to 'rank' is ambiguous
   59 |     rank[i] = 0;
      |     ^~~~
In file included from /usr/include/c++/14/bits/move.h:37,
                 from /usr/include/c++/14/bits/exception_ptr.h:41,
                 from /usr/include/c++/14/exception:166,
                 from /usr/include/c++/14/ios:41,
                 from /usr/include/c++/14/ostream:40,
                 from /usr/include/c++/14/iostream:41,
                 from a.cc:1:
/usr/include/c++/14/type_traits:1437:12: note: candidates are: 'template<class> struct std::rank'
 1437 |     struct rank
      |            ^~~~
a.cc:54:5: note:                 'int rank [100]'
   54 | int rank[100];
      |     ^~~~
a.cc: In function 'void unite(int, int)':
a.cc:73:6: error: reference to 'rank' is ambiguous
   73 |   if(rank[x] < rank[y])par[x] = y;
      |      ^~~~
/usr/include/c++/14/type_traits:1437:12: note: candidates are: 'template<class> struct std::rank'
 1437 |     struct rank
      |            ^~~~
a.cc:54:5: note:                 'int rank [100]'
   54 | int rank[100];
      |     ^~~~
a.cc:73:16: error: reference to 'rank' is ambiguous
   73 |   if(rank[x] < rank[y])par[x] = y;
      |                ^~~~
/usr/include/c++/14/type_traits:1437:12: note: candidates are: 'template<class> struct std::rank'
 1437 |     struct rank
      |            ^~~~
a.cc:54:5: note:                 'int rank [100]'
   54 | int rank[100];
      |     ^~~~
a.cc:76:8: error: reference to 'rank' is ambiguous
   76 |     if(rank[x] == rank[y])rank[x]++;
      |        ^~~~
/usr/include/c++/14/type_traits:1437:12: note: candidates are: 'template<class> struct std::rank'
 1437 |     struct rank
      |            ^~~~
a.cc:54:5: note:                 'int rank [100]'
   54 | int rank[100];
      |     ^~~~
a.cc:76:19: error: reference to 'rank' is ambiguous
   76 |     if(rank[x] == rank[y])rank[x]++;
      |                   ^~~~
/usr/include/c++/14/type_traits:1437:12: note: candidates are: 'template<class> struct std::rank'
 1437 |     struct rank
      |            ^~~~
a.cc:54:5: note:                 'int rank [100]'
   54 | int rank[100];
      |     ^~~~
a.cc:76:27: error: reference to 'rank' is ambiguous
   76 |     if(rank[x] == rank[y])rank[x]++;
      |                           ^~~~
/usr/include/c++/14/type_traits:1437:12: note: candidates are: 'template<class> struct std::rank'
 1437 |     struct rank
      |            ^~~~
a.cc:54:5: note:                 'int rank [100]'
   54 | int rank[100];
      |     ^~~~
a.cc: In function 'int main()':
a.cc:85:33: error: no match for 'operator>>' (operand types are 'std::istream' {aka 'std::basic_istream<char>'} and 'double')
   85 |         for(int k=0;k<4;k++)cin >> p[j][k].real() >> p[j][k].imag();
      |                             ~~~ ^~ ~~~~~~~~~~~~~~
      |                             |                  |
      |                             |                  double
      |                             std::istream {aka std::basic_istream<char>}
In file included from /usr/include/c++/14/iostream:42:
/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:85:48: error: cannot bind non-const lvalue reference of type 'bool&' to a value of type 'double'
   85 |         for(int k=0;k<4;k++)cin >> p[j][k].real() >> p[j][k].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:85:48: error: cannot bind non-const lvalue reference of type 'short int&' to a value of type 'double'
   85 |         for(int k=0;k<4;k++)cin >> p[j][k].real() >> p[j][k].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:85:48: error: cannot bind non-const lvalue reference of type 'short unsigned int&' to a value of type 'double'
   85 |         for(int k=0;k<4;k++)cin >> p[j][k].real() >> p[j][k].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:85:48: error: cannot bind non-const lvalue reference of type 'int&' to a value of type 'double'
   85 |         for(int k=0;k<4;k++)cin >> p[j][k].real() >> p[j][k].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:85:48: error: cannot bind non-const lvalue reference of type 'unsigned int&' to a value of type 'double'
   85 |         for(int k=0;k<4;k++)cin >> p[j][k].real() >> p[j][k].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:85:48: error: cannot bind non-const lvalue reference of type 'long int&' to a value of type 'double'
   85 |         for(int k=0;k<4;k++)cin >> p[j][k].real() >> p[j][k].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:85:48: error: cannot bind non-const lvalue reference of type 'long unsigned int&' to a value of type 'double'
   85 |         for(int k=0;k<4;k++)cin >> p[j][k].real() >> p[j][k].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:85:48: error: cannot bind non-const lvalue reference of type 'long long int&' to a value of type 'double'
   85 |         for(int k=0;k<4;k++)cin >> p[j][k].real() >> p[j][k].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:85:48: error: cannot bind non-const lvalue reference of type 'long long unsigned int&' to a value of type 'double'
   85 |         for(int k=0;k<4;k++)cin >> p[j][k].real() >> p[j][k].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:85:48: error: cannot bind non-const lvalue reference of type 'float&' to a value of type 'double'
   85 |         for(int k=0;k<4;k++)cin >> p[j][k].real() >> p[j][k].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_istrea