문제
https://www.acmicpc.net/problem/17779
17779번: 게리맨더링 2
재현시의 시장 구재현은 지난 몇 년간 게리맨더링을 통해서 자신의 당에게 유리하게 선거구를 획정했다. 견제할 권력이 없어진 구재현은 권력을 매우 부당하게 행사했고, 심지어는 시의 이름
www.acmicpc.net
내 풀이
문제 풀기 전에 인구수가 적힌 그리드의 인덱스가 1부터 시작한다는 점을 생각하고 가야 한다.
가장 고민을 많이 한 것은 '경계 안에 어떻게 5로 채울지'였다.
i번 행을 확인하면서 5가 2개 들어있는 행만 5의 위치를 알아내었다.
5가 i번 행의 a열과 i번 행의 b열에 있다면, i번 행의 a+1열에서 b열까지를 모두 5로 만들어주었다.
N = int(input())
# 1부터 시작하는 그리드
grid = [[0] + list(map(int, input().strip().split())) for _ in range(N)]
grid = [[0]*N] + grid
def board(x, y, d1, d2):
sector = [[0]*(N+1) for _ in range(N+1)]
num = [0]*(6)
# 1
dx, dy = [i for i in range(d1+1)], [j for j in range(d1+1)]
for i in range(len(dx)):
nx, ny = x+dx[i], y-dy[i]
if not sector[nx][ny]:
sector[nx][ny] = 5
num[5] += grid[nx][ny]
# 2
dx, dy = [i for i in range(d2+1)], [j for j in range(d2+1)]
for i in range(len(dx)):
nx, ny = x+dx[i], y+dy[i]
if not sector[nx][ny]:
sector[nx][ny] = 5
num[5] += grid[nx][ny]
# 3
dx, dy = [i for i in range(d1, d1+d2+1)], [j for j in range(d1, d1-d2-1, -1)]
for i in range(len(dx)):
nx, ny = x+dx[i], y-dy[i]
if not sector[nx][ny]:
sector[nx][ny] = 5
num[5] += grid[nx][ny]
# 4
dx, dy = [i for i in range(d2, d2+d1+1)], [j for j in range(d2, d2-d1-1, -1)]
for i in range(len(dx)):
nx, ny = x+dx[i], y+dy[i]
if not sector[nx][ny]:
sector[nx][ny] = 5
num[5] += grid[nx][ny]
# 경계안에 5로 채우기
for i in range(1, N+1):
five = []
if sector[i].count(5) == 2:
for j in range(1, N+1):
if sector[i][j] == 5:
five.append(j)
for j in range(five[0]+1, five[1]):
sector[i][j] = 5
num[5] += grid[i][j]
# 1, 2, 3, 4 채우기
for r in range(1, N+1):
for c in range(1, N+1):
if 1 <= r < x+d1 and 1 <= c <= y and not sector[r][c]:
sector[r][c] = 1
num[1] += grid[r][c]
elif 1 <= r <= x+d2 and y < c <= N and not sector[r][c]:
sector[r][c] = 2
num[2] += grid[r][c]
elif x+d1 <= r <= N and 1 <= c < y-d1+d2 and not sector[r][c]:
sector[r][c] = 3
num[3] += grid[r][c]
elif x+d2 < r <= N and y-d1+d2 <= c <= N and not sector[r][c]:
sector[r][c] = 4
num[4] += grid[r][c]
return max(num[1:]) - min(num[1:])
# d1, d2 최대값 N-1
MIN = 1e9
for d1 in range(1, N):
for d2 in range(1, N):
for x in range(1, N+1):
for y in range(1, N+1):
if x+d1+d2 <= N and 1 <= y-d1 <y and y+d2 <= N:
res = board(x, y, d1, d2)
MIN = min(MIN, res)
print(MIN)
총평
구현구현!
'알고리즘 > 삼성 기출' 카테고리의 다른 글
마법사 상어와 복제 [백준 23290번] (0) | 2022.10.12 |
---|---|
상어 중학교 [백준 21609번] (0) | 2022.10.11 |
톱니바퀴 [백준 14891번] (0) | 2022.10.09 |
아기 상어 [백준 16236번] (1) | 2022.10.08 |
나무 재테크 [백준 16235번] (1) | 2022.10.08 |