Language: C++

#include<iostream>
#include<vector>
#include<cmath>

using namespace std;

struct POINT{
  double x;
  double y;
};

struct CIRCLE{
  POINT p;
  double r;
};

struct DATA{
  double radian;
  int log;
};

int CheckCase(const CIRCLE, const CIRCLE);
double GetDistance(const CIRCLE, const CIRCLE);
void GetDigree(const CIRCLE, const CIRCLE, double&, double&);
void PushBackData(vector<DATA>&, double, int);
bool Compare(const DATA&, const DATA&);
double CalculateLength(const vector<DATA>, double);

int main(){
  int i, j, n, x, y, r, is_case;
  double t1, t2, sum;
  CIRCLE _circle;
  vector<CIRCLE> circle;
  vector<DATA> data;

  while(1){
    cin >> n;
    if(n == 0) break;

    for(i=0; i<n; ++i){
      cin >> x >> y >> r;
      _circle.p.x = (double)x;
      _circle.p.y = (double)y;
      _circle.r = (double)r;
      circle.push_back(_circle);
    }

    for(i=0, sum=0.0; i<circle.size(); ++i){
      for(j=0; j<circle.size(); ++j){
	is_case = CheckCase(circle[i], circle[j]);
	if(is_case == 1){
	  GetDigree(circle[i], circle[j], t1, t2);
	  if(t1 < 0) t1 += 2*M_PI;
	  if(t2 < 0) t2 += 2*M_PI;
	  if(t1 < t2){
	    PushBackData(data, t1, 1);
	    PushBackData(data, t2, -1);
	  }else{
	    PushBackData(data, 0.0, 1);
	    PushBackData(data, t2, -1);
	    PushBackData(data, t1, 1);
	    PushBackData(data, 2*M_PI, -1);
	  }
	}else if(is_case == 2){
	  data.clear();
	  PushBackData(data, 0.0, 1);
	  PushBackData(data, 2*M_PI, -1);
	  break;
	}
      }
      sort(data.begin(), data.end(), Compare);
      sum += CalculateLength(data, circle[i].r);
      data.clear();
    }
    cout.setf(ios::fixed, ios::floatfield);
    cout.precision(12);
    cout << sum << endl;
    circle.clear();
  }
  return 0;
}

int CheckCase(const CIRCLE c1, const CIRCLE c2){
  double d;
  d = GetDistance(c1, c2);
  if(c1.p.x == c2.p.x && c1.p.y == c2.p.y && c1.r == c2.r) return 0;
  if(d >= c1.r + c2.r)  return -1;
  if(c1.r >= c2.r + d) return 3;
  if(c2.r >= c1.r + d) return 2;
  return 1;
}

double GetDistance(const CIRCLE c1, const CIRCLE c2){
  double x, y;
  x = c1.p.x - c2.p.x;
  y = c1.p.y - c2.p.y;
  return sqrt(x*x + y*y);
}

void GetDigree(const CIRCLE c1, const CIRCLE c2, double& theta1, double& theta2){
  double a, b1, b2, t1, t2;
  CIRCLE c3;

  if(c1.p.x == c2.p.x){
    a = (c1.p.y*c1.p.y - c1.r*c1.r - c2.p.y*c2.p.y + c2.r*c2.r)
      /(2*(c1.p.y - c2.p.y));

    if(c1.p.y < c2.p.y){
      t1 = M_PI /2;
    t2 = acos((a - c1.p.y)/c1.r);
    }else{
      t1 = -M_PI /2;
      t2 = acos((c1.p.y - a)/c1.r);
    }
  }else if(c1.p.y == c2.p.y){
    a = (c1.p.x*c1.p.x - c1.r*c1.r - c2.p.x*c2.p.x + c2.r*c2.r)
      /(2*(c1.p.x - c2.p.x));

    if(c1.p.x < c2.p.x){
      t1 = 0.0;
      t2 = acos((a - c1.p.x)/c1.r);
    }else{
      t1 = M_PI;
      t2 = acos((c1.p.x - a)/c1.r);
    }
  }else{
    a = (c1.p.y - c2.p.y)/(c1.p.x - c2.p.x);
    b1 = c1.p.y - a * c1.p.x;
    b2 = (c1.p.x*c1.p.x + c1.p.y*c1.p.y - c1.r*c1.r
	  - c2.p.x*c2.p.x - c2.p.y*c2.p.y + c2.r*c2.r)/(2*(c1.p.y - c2.p.y));

    c3.p.x = a*(b2 - b1)/(a*a + 1);
    c3.p.y = (b2*a*a + b1)/(a*a + 1);

    if(c1.p.x < c2.p.x) t1 = atan(a);
    else t1 = atan(a) + M_PI;
    t2 = acos(GetDistance(c1, c3)/c1.r);
  }

  theta1 = t1 - t2;
  theta2 = t1 + t2;
}

void PushBackData(vector<DATA>& data, double radian, int log){
  DATA _data;
  _data.radian = radian;
  _data.log = log;
  data.push_back(_data);
}

bool Compare(const DATA& x, const DATA& y){
  if(x.radian == y.radian)
    return x.log > y.log; 
  else
    return x.radian < y.radian;
}

double CalculateLength(const vector<DATA> data, double r){
  int i, j, count;
  double radian;
  for(i=0, j=0, count=0, radian=0.0; j<data.size(); ++j){
    count += data[j].log;
    if(count == 0){
      radian += (data[j].radian - data[i].radian);
      i = j + 1;
    }
  }
  return r*(2*M_PI - radian);
}

Compiler output:
a.cc: In function 'int main()':
a.cc:71:7: error: 'sort' was not declared in this scope; did you mean 'sqrt'?
   71 |       sort(data.begin(), data.end(), Compare);
      |       ^~~~
      |       sqrt