Problem:
Problem 07: Crop Circle

アルゼンチンの広大な農地に突如ミステリーサークルが出没した。ミステリーサークルは重なっているもの、ポツンとあるもの、大きいもの、小さいものと合計 n 個確認された。

あるミステリーハンターが空中からミステリーサークルの全体像を撮影しようと試みたところ、各円の輪郭がはっきりしていなかったため、映像にその美しい模様を映し出すことが難しいことが分かった。

そこで、そのミステリーハンターは輪郭に沿って特殊素材の紐を設置し、輪郭を強調する提案をした。

紐を設置する部分は、あるミステリーサークルの円周上で、他のどのミステリーサークルにも含まれない部分である。

撮影隊は必要な紐の長さを計測するために、プログラムの作成をあなたに依頼した。各ミステリーサークルの中心座標と半径を入力し、設置する紐の長さを報告するプログラムを作成せよ。

参考として入出力例の１つ目と２つ目のケースをそれぞれ図１、図２に示す。紐の部分が太い線で示されている。

図１

図２

Input

入力として複数のデータセットが与えられる。各データセットは以下の形式で与えられる：

n　（ミステリーサークルの数：整数）

x1 y1 r1 　（1 個目のサークルの中心座標と半径：空白区切りの実数）

x2 y2 r2 　（2 個目のサークルの中心座標と半径：空白区切りの実数）

.

.

xn yn rn 　（n 個目のサークルの中心座標と半径：空白区切りの実数）

n が 0 のとき、入力の終わりを示す。

Output

各データセットに対して、紐の長さを１行に出力せよ。出力は 0.000001 以下の誤差を含んでもよい。

Constraints

n ≤ 100

-1000 ≤ xi, yi ≤ 1000

0 < ri ≤ 100

Sample Input

4
6 4 2
4 7 3
7 10 3
13 6 1
4
7 4 2
4 7 3
7 10 3
11 6 3
0

Output for the Sample Input

39.664699289572
45.627024663706

Solution in Ruby (judge verdict: Wrong Answer)

include Math

def inc(arr,x2,y2,r2)
	del = []
	arr.each{|cir|
		x1,y1,r1 = cir
		d2 = ((x1-x2)**2 + (y1-y2)**2)
		if (((r1-r2)**2) >= d2 ) then
			if r1 < r2 then
				del.push(cir)
			else
				return
			end
		end
	}
	
	del.each{|cir|
		arr.delete(cir)
	}
	arr.push([x2,y2,r2])
end

def calc(arr)
	ans = 0
	while(!arr.empty?) do
		cir1 = arr.pop
		x1,y1,r1 = cir1
		ans += r1 * 2 * PI
		arr.each{|cir2|
			x2,y2,r2 = cir2
			d2 = ((x1-x2)**2 + (y1-y2)**2)
			if ((r1 - r2) ** 2) < d2 and (d2 < ((r1 + r2) ** 2)) then
				d = sqrt(d2)
				r12 = r1**2
				r22 = r2**2
				theta1 = Math.acos((d2+r12-r22)/(2*d*r1))
				theta2 = Math.acos((d2-r12+r22)/(2*d*r2))
				ans -= (r1 * theta1 + r2 * theta2) * 2
			end
		}
	end
	return ans
end

loop do
	n = gets.to_i
	if (n == 0) then
		exit
	end
	
	arr = []
	sum = 0
	n.times{|i|	
		x,y,r = gets.chomp.split.map(&:to_i)
		inc(arr,x,y,r)
	}
	p calc(arr)
end