ebisukeプログラミング初心者脱出黙示録

30歳を過ぎてから始めたプログラミングと競プロの記録。Pythonで取り組んでいます。Arduinoで電子工作も

AtCoder-ABC207 C - Many Segments【Python解答例】

f:id:ebisuke33:20210626224851p:plain

AtCoder Beginner Contest207のC問題についてPythonの解答例を記事にしていきます。
AtCoder Beginner Contest 207 - AtCoder



AtCoder Beginner Contest207 C - Many Segments

C - Many Segments

問題文

1 から N までの番号が付いた N 個の区間が与えられます。区間 i は、
・ti=1 なら [li,ri]
・ti=2 なら [li,ri)
・ti=3 なら (li,ri]
・ti=4 なら (li,ri)です。

1≤i

制約

・2≤N≤2000
・1≤ti≤4
・1≤li

解答例

n = int(input())

T = []
L = []
R = []
for i in range(n):
    t, l, r = map(int,input().split())
    T.append(t)
    L.append(l)
    R.append(r)

ans = 0
for i in range(n):
    for j in range(i+1, n):
        if T[i] == 1 or T[i] == 2:
            min_i = L[i]
        elif T[i] == 3 or T[i] == 4:
            min_i = L[i] + 0.1
        if T[i] == 1 or T[i] == 3:
            max_i = R[i]
        elif T[i] == 2 or T[i] == 4:
            max_i = R[i] - 0.1

        if T[j] == 1 or T[j] == 2:
            min_j = L[j]
        elif T[j] == 3 or T[j] == 4:
            min_j = L[j] + 0.1
        if T[j] == 1 or T[j] == 3:
            max_j = R[j]
        elif T[j] == 2 or T[j] == 4:
            max_j = R[j] - 0.1
        
        if min_j >= min_i and min_j <= max_i:
            ans += 1
        elif max_j >= min_i and max_j <= max_i:
            ans += 1
        elif min_i >= min_j and min_i <= max_j:
            ans += 1
        elif max_i >= min_j and max_i <= max_j:
            ans += 1
        
print(ans)

解説

区間か開区間があるN個の区間があり、共通区間を持つ区間の組み合わせの数を求める問題です。

めちゃくちゃ場合分けの多いコードになっています。
公式解説のほうがとてもすっきり書かれているのでそちらを参照したほうがいいです (^_^;)

i区間とj区間においてmax_i/jとmin_i/jで端点を比較しました。
区間の場合は0.1だけ値を変更しました。

お互いの端点に共通区間があるか4つの場合分けで判定しましたが、この判定も公式解説がスマートです。

共通区間があればansに1を足していき、ループを抜けた後にansを出力すればOKでしたが、参考にしないほうがいいコードだと思います。
スマートな方法を早く思いつけるよう精進していきたいです。


ABC207の関連記事はこちら
ebisuke33.hatenablog.com