πλ¬Έμ νμνκΈ°
- ν¬κΈ°κ° NxNμΈ μ μ¬κ°νμ λ
μ΄ μκ³ , λ
μ λ¨μ μ μ¬κ°ν 1x1λ‘ λλμ΄μ Έ μμ
- κ° λ¨μ μ μ¬κ°ν(i,j)μ μμ΅μ A(i,j) (μμκ° λ μλ μμ)
- λ
μ μΌλΆλ₯Ό λ μ¬λμκ² λλ μ£Όκ³ μ ν¨
- λ μ¬λμ΄ λ°κ²λλ λ μ νμ μ§μ¬κ°ν λͺ¨μμ΄κ³ , λ³μ μΆμ νν
- λ μ¬λμ΄ λμ¬μ§μ λ
μ μμ΅μ ν©μ΄ κ°κ² λλλ‘ νλ©°, λ λ
μ΄ κΌμ§μ νλμμλ§ λ§λλλ‘ νλ λ°©λ²μ μ ꡬνκΈ°
- λ λ μ΄ λ³μ 곡μ ν μλ μμ
μ λ ₯
- λ μ ν¬κΈ° N (1 ≤ N ≤ 50)
- Nκ°μ μ€μ κ±Έμ³ Nκ°μ μ«μκ° μ£Όμ΄μ§λ©°, A(i,j)λ λΆλΆ μ μ¬κ°ν (i,j)μ μμ΅ (-1000 < A(i,j) < 1000)
μΆλ ₯
- 쑰건μ λ§μ‘±νλ©΄μ λ μ λΉλ €μ£Όλ λ°©λ²μ μ μΆλ ₯
νμ΄ λ°©λ² μκ°ν΄λ³΄κΈ°
첫λ²μ§Έ μ¬λμ΄ λ°μ μ μλ λ μ λ¨Όμ λΈλ£¨νΈν¬μ€ νμνκ³ , κ° μ νλ λ μ λν΄ μ€λ₯Έμͺ½ μ κΌμ§μ λλ μ€λ₯Έμͺ½ μλ κΌμ§μ νλλ§ κ³΅μ νλ, 첫λ²μ§Έ μ¬λμ΄ λ°μ λ μ μμ΅κ³Ό λλ²μ§Έ μ¬λμ΄ λ°μ μμ΅μ΄ κ°λλ‘ λ μ μ ννλ κ°μ§μλ₯Ό ꡬνλ©΄ λλ€. (λͺ¨λ κΌμ§μ μ λν΄ κ²½μ°μ μλ₯Ό ꡬν΄λ²λ¦¬λ©΄ μ€λ³΅μ΄ λ°μνλ―λ‘ μ€λ₯Έμͺ½ μ, μ€λ₯Έμͺ½ μλ 2κ°λ§ νμΈ)
μ΄λ, (0, 0)λΆν° (i,j)κΉμ§μ λ μ μ ννμ λμ λμ ν©μ κ΅¬ν΄ μ νλ λ μ μμ΅μ ꡬνκΈ° μ©μ΄νκ² νλ€.
πμ½λ μ€κ³νκΈ°
- λ μ ν¬κΈ° Nμ μ λ ₯λ°λλ€.
- κ° λ¨μ μ μ¬κ°ν λ μ μμ΅μ μ μ₯ν μ΄μ°¨μ 리μ€νΈ profitμ μμ±νκ³ , κ°μ μ λ ₯λ°λλ€.
- λ°©λ²μ μλ₯Ό μ μ₯ν λ³μ countλ₯Ό μμ±νκ³ 0μΌλ‘ μ΄κΈ°ννλ€.
- (0,0)μ μΌμͺ½ μ κΌμ§μ μΌλ‘ νκ³ (i,j)μ μ€λ₯Έμͺ½ μλ κΌμ§μ μΌλ‘ νλ μ§μ¬κ°νμΌλ‘ λ μ μ ννμ λ, λͺ¨λ λ μ μμ΅μ μ μ₯ν (N+1)x(N+1) μ΄μ°¨μ 리μ€νΈ prefix_profitμ μμ±νλ€.
- prefix_profitμ μννλ©΄μ, prefix_profit(i,j)μ λν΄ prefix_profix(i-1, j) + prefix_profit(i, j-1) - prefix_profit(i-1,j-1) + profit(i-1, j-1)λ₯Ό μ μ₯νλ€.
- (i,j)λ₯Ό μΌμͺ½ μλ κΌμ§μ μΌλ‘ κ°μ§λ μ§μ¬κ°νμ μμ΅μ λν΄ κ°μ§μλ₯Ό μ μ₯ν (N+1)x(N+1) μ΄μ°¨μ 리μ€νΈ left_bottom_rectangleκ³Ό λ§μ°¬κ°μ§λ‘ (i,j)λ₯Ό μΌμͺ½ μ κΌμ§μ μΌλ‘ κ°μ§λ μ§μ¬κ°νμ μμ΅μ λν΄ κ°μ§μλ₯Ό μ μ₯ν μ΄μ°¨μ 리μ€νΈ left_top_rectangleμ μμ±νκ³ , λͺ¨λ μμλ₯Ό defaultdict(int)λ‘ μ΄κΈ°ννλ€.
- μλ₯Ό λ€μ΄, left_bottom_rectangle[x][y][n]μ (x,y)λ₯Ό μΌμͺ½ μλ κΌμ§μ μΌλ‘ κ°λ μ§μ¬κ°ν μμ μ€ μμ΅μ΄ nμΈ μμμ κ°μ§μλ₯Ό μ μ₯ν¨
- (1 ≤ x1 < N, 1 ≤ y1 < N), (x1 < x2 < N+1, y1 < y2 < N+1)μ λ²μλ‘ 4μ€ forλ¬Έ νμνλ©΄μ λμ¬ μ μλ λͺ¨λ μ§μ¬κ°ν μμμ κ²½μ°λ₯Ό ꡬνλ€. μ΄ν, ν΄λΉ μ§μ¬κ°ν μμμ μμ΅μ ꡬνκ³ , left_bottom_rectangle[x2][y1][μμ΅]κ³Ό left_top_rectangle[x1][y1][μμ΅] κ°κ°μ 1μ λνλ€.
- 4μ€ forλ¬Έμ ν΅ν΄ 첫λ²μ§Έ μ¬λμ΄ κ°μ Έκ° λ μ μΌμͺ½ μ κΌμ§μ (x1,y1), μ€λ₯Έμͺ½ μλ κΌμ§μ (x2,y2)μ κ²½μ°μ μλ₯Ό λͺ¨λ ꡬνκ³ , κ° κ²½μ°μ λν΄ μμ΅μ ꡬν΄μ left_bottom_rectangle[x1][y2][μμ΅]κ³Ό left_top_rectangle[x2][y2]λ₯Ό countμ λνλ€.
- countλ₯Ό μΆλ ₯νλ€.
πμλ νμ°¨ μμ μ¬ν
- 1νμ°¨ (μκ°μ΄κ³Ό)
import sys
input = sys.stdin.readline
N = int(input())
profit = [list(map(int, input().split())) for _ in range(N)]
count = 0
prefix_sum_profit = [[0]*(N+1) for _ in range(N+1)]
for i in range(1, N+1):
for j in range(1, N+1):
prefix_sum_profit[i][j] = prefix_sum_profit[i][j-1] + prefix_sum_profit[i-1][j] - prefix_sum_profit[i-1][j-1] + profit[i-1][j-1]
def get_total_profit(x1, y1, x2, y2):
return prefix_sum_profit[x2][y2] - prefix_sum_profit[x1][y2] - prefix_sum_profit[x2][y1] + prefix_sum_profit[x1][y1]
def find_valiable_cases(x1, y1, x2, y2):
global count
current_total_profit = get_total_profit(x1, y1, x2, y2)
for a in range(x1):
for b in range(y2, N+1):
if get_total_profit(a, y2, x1, b) == current_total_profit:
count += 1
for a in range(x2+1, N+1):
for b in range(y2+1, N+1):
if get_total_profit(x2, y2, a, b) == current_total_profit:
count += 1
for x1 in range(N):
for y1 in range(N):
for x2 in range(x1+1, N+1):
for y2 in range(y1+1, N+1):
find_valiable_cases(x1, y1, x2, y2)
print(count)
μμ κ°μ΄ O(NβΆ)μ μκ°λ³΅μ‘λλ₯Ό κ°λ μ½λλ₯Ό μ μΆνλ€. κ²°κ³Όλ μμ μκ°μ΄κ³Ό.
μ μ½λλ₯Ό "첫λ²μ§Έ μμμ μ’νλ₯Ό ꡬνκ³ , μ€λ₯Έμͺ½ μ κΌμ§μ μ 곡μ νκ±°λ μ€λ₯Έμͺ½ μλ κΌμ§μ μ 곡μ νλ μμ μ€ μ²«λ²μ§Έ μμ μμ΅μ΄λ κ°μ κ² κ°μ ꡬνκΈ°"λΌλ κΈ°λ³Έ λ‘μ§μ λκ°μ΄ κ°μ Έκ° μ±λ‘ μμ νλ€.
첫λ²μ§Έ μμμ΄ κ²°μ λλ©΄ λλ²μ§Έ μμμ μμ νμ(O(N²))νλ κ²μ΄ μλλΌ, 미리 ν΄μλ§΅μ ν΅ν΄ μ€λ₯Έμͺ½ μ κΌμ§μ μ κ°μ§λ μμμμ λμ¬ μ μλ μμ΅μ κ°μ§μ, μ€λ₯Έμͺ½ μλ κΌμ§μ μ κ°μ§λ μμμμ λμ¬ μ μλ μμ΅μ κ°μ§μλ₯Ό ꡬν΄λκ³ μ΄λ₯Ό νμ©(O(1))νλλ‘ μμ νλ€.
π μ λ΅ μ½λ
from collections import defaultdict
import sys
input = sys.stdin.readline
N = int(input())
profit = [list(map(int, input().split())) for _ in range(N)]
prefix_profit = [[0]*(N+1) for _ in range(N+1)]
for i in range(1, N+1):
for j in range(1, N+1):
prefix_profit[i][j] = prefix_profit[i-1][j] + prefix_profit[i][j-1] - prefix_profit[i-1][j-1] + profit[i-1][j-1]
left_bottom_rectangle = [[defaultdict(int) for _ in range(N+1)] for _ in range(N+1)]
left_top_rectangle = [[defaultdict(int) for _ in range(N+1)] for _ in range(N+1)]
for x1 in range(N):
for y1 in range(N):
for x2 in range(x1+1, N+1):
for y2 in range(y1+1, N+1):
current_rectangle = prefix_profit[x2][y2] - prefix_profit[x1][y2] - prefix_profit[x2][y1] + prefix_profit[x1][y1]
left_bottom_rectangle[x2][y1][current_rectangle] += 1
left_top_rectangle[x1][y1][current_rectangle] += 1
count = 0
for x1 in range(N):
for y1 in range(N):
for x2 in range(x1+1, N+1):
for y2 in range(y1+1, N+1):
current_rectangle = prefix_profit[x2][y2] - prefix_profit[x1][y2] - prefix_profit[x2][y1] + prefix_profit[x1][y1]
count += left_bottom_rectangle[x1][y2][current_rectangle]
count += left_top_rectangle[x2][y2][current_rectangle]
print(count)