第12回 JOI 予選 E 魚の生息範囲【Python】

問題はこちら

3次元の座標圧縮 & 累積和。コードは長いけどやってることは単純。

# 入力
N, K = map(int, input().split())
X, Y, D = [], [], []
plot = []
for _ in range(N):
   x_1, y_1, d_1, x_2, y_2, d_2 = map(int, input().split())
   X.append(x_1); X.append(x_2)
   Y.append(y_1); Y.append(y_2)
   D.append(d_1); D.append(d_2)
   plot.append((x_1, y_1, d_1, 1))
   plot.append((x_2, y_1, d_1, -1))
   plot.append((x_1, y_2, d_1, -1))
   plot.append((x_1, y_1, d_2, -1))
   plot.append((x_1, y_2, d_2, 1))
   plot.append((x_2, y_1, d_2, 1))
   plot.append((x_2, y_2, d_1, 1))
   plot.append((x_2, y_2, d_2, -1))


# 座標からindexを対応させる辞書を作る
X = list(set(X)); Y = list(set(Y)); D = list(set(D))
X.sort(); Y.sort(); D.sort()
indX = {x:i + 1 for i, x in enumerate(X)}
indY = {y:i + 1 for i, y in enumerate(Y)}
indD = {d:i + 1 for i, d in enumerate(D)}


# 累積和の初期化
S = [[[0]*(2*N + 1) for _ in range(2*N + 1)] for _ in range(2*N + 1)]
for x, y, d, w in plot:
   i, j, k = indX[x], indY[y], indD[d]
   S[i][j][k] += w
   

# 累積和の計算
for i in range(1, 2*N + 1):
   for j in range(1, 2*N + 1):
       for k in range(1, 2*N + 1):
           S[i][j][k] += S[i - 1][j][k] + S[i][j - 1][k] + S[i][j][k - 1]\
               - S[i][j - 1][k - 1] - S[i - 1][j][k - 1] - S[i - 1][j - 1][k]\
                   + S[i - 1][j - 1][k - 1]
                   

# 答えの計算       
ans = 0
for i in range(1, 2*N + 1):
   for j in range(1, 2*N + 1):
       for k in range(1, 2*N + 1):
           if S[i][j][k] >= K:
               ans += (X[i] - X[i - 1]) * (Y[j] - Y[j - 1]) * (D[k] - D[k - 1])


# 出力
print(ans)


この記事が気に入ったらサポートをしてみませんか?