ABC143 D - Triangles
問題原文
問題要旨
互いに区別できる 本の棒がある。 番目の棒の長さは、 である。
これらの棒から3本の棒を使って、三角形を作る時、作れる三角形は何種類あるか。
ただし2つの三角形は、ある棒が一方にのみ使われているときに異なるとする。
また、三角形が成立する条件は、 (最も長い棒の長さ) < (それ以外の棒の長さの和) となるときである。
解法
重複なく数えられるようちゃんと気配りする。
棒の選ぶ順番に意味がないので、選ぶ棒の長さを として、 となるように選ぶことにする。
最も短い棒と、その次に短い棒を固定する。(これらの長さを とする)
すると、三角形が成立するような最も長い棒の長さは、 未満であって、 より長いもの(これは自明に成り立つ)である必要がある。
そのような棒の数は、あらかじめ棒をソートしておいて、二分探索で数えることができる。
このとき、条件を満たすような棒であっても、 番目より小さい棒はカウントしないこと。(a, b, c の index がそれぞれ i, j, (最も長い棒) となるようにする)
実装
下手に組み合わせ計算に走ると破滅するので、ぐっと堪えて楽な方法を探す。
from bisect import bisect_left N = int(input()) L = sorted(list(map(int, input().split()))) ans = 0 for i in range(N): # 1番短い棒 for j in range(i + 1, N): # 真ん中の長さの棒 ans += bisect_left(L, L[i] + L[j]) - (j + 1) print(ans)
感想
i < j < (最も長い棒のindex) を常に意識する。