1451-長方形に分割
31319 ワード
📚 1451-長方形に分割
長方形に分割
理解する
勘定科目の合計(1,1)~(n,m)
各席合計
(1,1)~(2,2)の総和
(2, 2) = (1, 2) + (2, 1) - (1, 1)
→なぜ(1,1)を外しますか?(1,2)と(2,1)に(1,2)を加える.
(2,2)~(3,3)までの総和
(3, 3) = (2, 3) + (3, 2) - (2, 2)
→なぜ(2,2)を外しますか?(2,3)と(3,2)に(2,2)を加えて2回.
ex)
既存のマトリクス
1365781078
(1,1)行から(n,m)行列までの総和.
|1|4|10|
|-|-|-|
|6|16|30|
|16|33|55|
次のようにします.
現在の(1,1)行列から(3,3)行列までは和で構成されている.
14(1+3)10(1+3+6)6(1+5)16(7+5+3+1)3016(1+5+10)3355
(2,2)から(3,3)までの合計はいくらですか.
(1,1)から見始めたとき
(2,2)~(3,3)以外の部分は外します.
xxxxx
でも考えてみれば.
(1, 1) ~ (3, 1)
の合計は(3, 1)
に格納される.(1, 1) ~ (1, 3)
の合計は(1, 3)
に格納される.55(3, 3) - 16(3, 1) - 10(1, 3) + 1(1, 1)
→なぜ1(1, 1)
→見て、(3, 1)
統合で増加(1, 1)
、(1, 3)
統合で増加(1, 1)
.よって、(1, 1)
2回減じ、必要+1(1, 1)
.テストソース
arr = [[0, 1, 3, 6], [0, 5, 7, 8],[0, 10,7,8]]
print(sum(arr[0]) + sum(arr[1]))
result = [[0] * 5 for _ in range(5)]
arr = [[0]] + arr
print("arr : ", arr)
for i in range(1, 4):
for j in range(1, 4):
result[i][j] = result[i - 1][j] + result[i][j - 1] - result[i - 1][j - 1] + arr[i][j]
def sum_cal(x1, y1, x2, y2):
print(result[x2][y2], result[x2][y1 - 1], result[x1 - 1][y2], result[x1 - 1][y1 - 1])
return result[x2][y2] - result[x2][y1 - 1] - result[x1 - 1][y2] + result[x1 - 1][y1 - 1]
print("result : ", result)
print(sum_cal(2, 2, 3, 3))
結果
30
arr : [[0], [0, 1, 3, 6], [0, 5, 7, 8], [0, 10, 7, 8]]
result : [[0, 0, 0, 0, 0], [0, 1, 4, 10, 0], [0, 6, 16, 30, 0], [0, 16, 33, 55, 0], [0, 0, 0, 0, 0]]
55 16 10 1
30
✔¥矩形が3つに分かれている場合
(1)
|o|x|t|
|-|-|-|-|
|o|x|t|
(1, 1) ~ (n, i)
(1, i+1) ~ (n, j)
(1, j+1) ~ (n, m)
|o|o|
|-|-|-|-|
|x|x|
|t|t|
(1, 1) ~ (i, m)
(i+1, 1) ~ (j, m)
(j+1, 1) ~ (n, m)
|o|x|x|
|-|-|-|-|
|o|t|t|
(1, 1) ~ (n, i)
(1, i+1) ~ (j, m)
(j+1, i+1) ~ (n, m)
|o|o|x|
|-|-|-|-|
|t|t|x|
(1, 1) ~ (i, j)
(i+1, 1) ~ (n, j)
(1, j+1) ~ (n, m)
|o|o|
|-|-|-|-|
|x|t|
|x|t|
(1, 1) ~ (i, m)
(i+1, 1) ~ (n, j)
(i+1, j+1) ~ (n, m)
|o|x|
|-|-|-|-|
|o|x|
|t|t|
(1, 1) ~ (i, j)
(1, j+1) ~ (i, m)
(i+1, 1) ~ (n, m)
ソース
import sys
read = sys.stdin.readline
n, m = map(int, read().split())
arr = [[0] * (m + 1)]
for i in range(n):
arr.append([0] + list(map(int, read().strip())))
sum_rec = [[0] * (m + 1) for _ in range(n + 1)]
# (1, 1)부터 (n, m)까지 각 자리의 총합
for i in range(1, n + 1):
for j in range(1, m + 1):
sum_rec[i][j] = arr[i][j] + sum_rec[i - 1][j] + sum_rec[i][j - 1] - sum_rec[i - 1][j - 1]
# 각 자리수 총합을 이용해 (a, b)부터 (n, m)까지 합
def sum_of_rec(x1, y1, x2, y2):
# print(sum_rec[x2][y2], sum_rec[x1 - 1][y2], sum_rec[x2][y1 - 1], y2)
return sum_rec[x2][y2] - sum_rec[x1 - 1][y2] - sum_rec[x2][y1 - 1] + sum_rec[x1 - 1][y1 - 1]
result = 0
ans = 0
# (1) 전체 직사각형을 세로로만 분할한 경우
for i in range(1, m - 1):
for j in range(i + 1, m):
num1 = sum_of_rec(1, 1, n, i)
num2 = sum_of_rec(1, i + 1, n, j)
num3 = sum_of_rec(1, j + 1, n, m)
if result < num1 * num2 * num3:
result = num1 * num2 * num3
# (2) 전체 직사각형을 가로로만 분할한 경우
for i in range(1, n - 1):
for j in range(i + 1, n):
num1 = sum_of_rec(1, 1, i, m)
num2 = sum_of_rec(i + 1, 1, j, m)
num3 = sum_of_rec(j + 1, 1, n, m)
if result < num1 * num2 * num3:
result = num1 * num2 * num3
# (3) 전체 세로 분할 후, 우측 가로 분할한 경우
for i in range(1, m):
for j in range(1, n):
num1 = sum_of_rec(1, 1, n, i)
num2 = sum_of_rec(1, i + 1, j, m)
num3 = sum_of_rec(j + 1, i + 1, n, m)
if result < num1 * num2 * num3:
result = num1 * num2 * num3
# (4) 전체 세로 분할 후, 좌측 가로 분할한 경우
for i in range(1, n):
for j in range(1, m):
num1 = sum_of_rec(1, 1, i, j)
num2 = sum_of_rec(i + 1, 1, n, j)
num3 = sum_of_rec(1, j + 1, n, m)
if result < num1 * num2 * num3:
result = num1 * num2 * num3
# (5) 전체 가로 분할 후, 하단 세로 분할한 경우
for i in range(1, n):
for j in range(1, m):
num1 = sum_of_rec(1, 1, i, m)
num2 = sum_of_rec(i + 1, 1, n, j)
num3 = sum_of_rec(i + 1, j + 1, n, m)
if result < num1 * num2 * num3:
result = num1 * num2 * num3
# (6) 전체 가로 분할 후, 상단 세로 분할한 경우
for i in range(1, n):
for j in range(1, m):
num1 = sum_of_rec(1, 1, i, j)
num2 = sum_of_rec(1, j + 1, i, m)
num3 = sum_of_rec(i + 1, 1, n, m)
if result < num1 * num2 * num3:
result = num1 * num2 * num3
print(result)
採点結果
问题解决には、间违った変数を1つ入力してしまったので、ずっと间违っていました(1位置にiを入力して)、探すのに长い时间がかかりましたが、多くの変数を使っていたら、単独でメモを整理して、ソースを书きましょう!!
Reference
この問題について(1451-長方形に分割), 我々は、より多くの情報をここで見つけました https://velog.io/@chang626/1451-직사각형으로-나누기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol