0
0

paizaラーニング問題集「二次元区間和」を解いてみた

Last updated at Posted at 2024-09-12

▼感想:

区間和の計算方法のやりかたを踏まえて、本問を解くことができました。

縦方向の変数(y,H,ruisekiwa_tate,j,a,c)と
横方向の変数(x,W,ruisekiwa_yoko,i,b,d)を
しっかり定め、混同しないように気を付けました。

二次元区間和が、横長か縦長か、に応じて処理を分けました。

▼コード:

########## 処理0(準備) インプット,リスト定義など ###########

H,W,N = map(int,input().split())

A = [[0 for i in range(W)] for j in range(H)]

# ruisekiwa_yoko,ruisekiwa_tate: 横方向,縦方向の累積和格納用リスト
ruisekiwa_yoko = [[0 for i in range(W)] for j in range(H)]
ruisekiwa_tate = [[0 for i in range(W)] for j in range(H)]

########## 処理1 横方向の累積和の計算、格納 ##########

for j in range(H):

    A[j] = list(map(int,input().split()))

    ruisekiwa_yoko[j][0] = A[j][0]

    for i in range(W-1):
        ruisekiwa_yoko[j][i+1] = ruisekiwa_yoko[j][i] + A[j][i+1]

########## 処理2 縦方向の累積和の計算、格納 ##########

for i in range(W):

    ruisekiwa_tate[0][i] = A[0][i]

    for j in range(H-1):
        ruisekiwa_tate[j+1][i] = ruisekiwa_tate[j][i] + A[j+1][i]

########## 処理3 入力に応じた区間和の計算 ##########

for _ in range(N):

    # total: 計算した区間和の格納用変数
    total = 0
    a,b,c,d = map(int,input().split())

    # 入力が横長
    if c-a < d-b:
        # 横方向の区間の左端が1
        if b == 1:
            for j in range(c-a+1):
                total += ruisekiwa_yoko[a-1+j][d-1]
        else:
            for j in range(c-a+1):
                total += (ruisekiwa_yoko[a-1+j][d-1] - ruisekiwa_yoko[a-1+j][b-1-1])
        
    # 入力が縦長、または横と縦が同じ長さ
    else:
        # 縦方向の区間の上端が1
        if a == 1:
            for i in range(d-b+1):
                total += ruisekiwa_tate[c-1][b-1+i]
        else:
            for i in range(d-b+1):
                total += (ruisekiwa_tate[c-1][b-1+i] - ruisekiwa_tate[a-1-1][b-1+i])
            
    print(total)
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0