일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 보석 쇼핑
- 16234번
- 1038번
- 12869번
- 15686번
- 스타트 택시
- 12865번
- 19238번
- 17144번
- 백준 알고리즘
- 프로그래머스
- 2020 카카오 인턴십
- python
- HTML 기초
- 빛의 경로 사이클
- 경주로 건설
- 9095번
- 키패드 누르기
- 1789번
- 어른 상어
- 베스트엘범
- SW Expert Academy
- 14499번
- 미세먼지 안녕!
- 수식 최대화
- SW ExpertAcademy
- 감소하는 수
- QueryDSL 기초
- 파이썬
- 거울 설치
Archives
- Today
- Total
보물창고 블로그
백준 알고리즘 17779번 게리맨더링 2 풀이 with Python 본문
728x90
문제 링크:https://www.acmicpc.net/problem/17779
17779번: 게리맨더링 2
재현시의 시장 구재현은 지난 몇 년간 게리맨더링을 통해서 자신의 당에게 유리하게 선거구를 획정했다. 견제할 권력이 없어진 구재현은 권력을 매우 부당하게 행사했고, 심지어는 시의 이름도 재현시로 변경했다. 이번 선거에서는 최대한 공평하게 선거구를 획정하려고 한다. 재현시는 크기가 N×N인 격자로 나타낼 수 있다. 격자의 각 칸은 구역을 의미하고, r행 c열에 있는 구역은 (r, c)로 나타낼 수 있다. 구역을 다섯 개의 선거구로 나눠야 하고, 각 구역은 다
www.acmicpc.net
문제는 다음과 같습니다.
이 문제의 핵심 구현은 먼저 x, y, d1, d2가 주어졌을 때, 5개의 선거구역을 올바르게 나누는 것과 x,y,d1,d2가 가능한 범위를 제한하여서 for문을 돌리는 것이 핵심문제였다. 처음에 5개의 선거구역을 나누는 것에 꽤 시간을 허비하였다.
같이 공부하는 스터디원들은 구역별로 따로 구하였지만 나는 먼저 맵에다가 5개의 구역을 나누어서 그것에 해당하는 구역 값을 구하는 방식을 사용하여 비효율적이지만 비교적 쉽게 코딩을 하였다. 내가 해결한 코드는 다음과 같다.
"""solution함수는 x,y,d1,d2값과 맵의 전체 크기의 한변인 n과 선거구 인원인 p가 주어졌을 때,
선거구의 인원수의 최대값과 최솟값의 차를 반환하는 함수입니다."""
def solution(x,y,d1,d2,n,p):
#area는 각 선거구의 인원수를 받는다.
area=[0 for _ in range(5)]
#map1은 각 구역을 선거구역으로 나누기 위해 만든 맵
map1=[[0 for _ in range(n)] for _ in range(n)]
# 먼저 경계선을 구역5로 할당한다.
for i in range(d1+1):
map1[x+i][y-i]=5
map1[x+d2+i][y+d2-i]=5
for i in range(d2+1):
map1[x+i][y+i]=5
map1[x+d1+i][y-d1+i]=5
for i in range(d1):
k=1
while(map1[x+i+k][y-i]!=5):
map1[x+i+k][y-i]=5
k+=1
#경계선 내부구역을 구역 5로 지정
for i in range(d2):
k=1
while(map1[x+i+k][y+i]!=5):
map1[x+i+k][y+i]=5
k+=1
#경계선 외부 구역을 구역1~4로 각각 나눈다.
for i in range(n):
for j in range(n):
#구역1
if i<x+d1 and j<=y and map1[i][j]==0:
map1[i][j]=1
#구역2
elif i<=x+d2 and j>y and map1[i][j]==0:
map1[i][j]=2
#구역3
elif x+d1<=i and j<y-d1+d2 and map1[i][j]==0:
map1[i][j]=3
#구역4
elif i>x+d2 and j>=y-d1+d2 and map1[i][j]==0:
map1[i][j]=4
#이제 map1의 값에 따라 area값을 추가해준다.
for i in range(n):
for j in range(n):
area[map1[i][j]-1]+=p[i][j]
# 구역의 최댓값과 최솟값의 차이를 반환한다.
return (max(area)-min(area))
# 구역 크기인 n을 받는다.
n=int(input())
# 최종값인 answer를 -1로 선언
answer=-1
# 각 셀마다 인구수를 population에 입력 받는다.
population=[]
for _ in range(n):
population.append(list(map(int,input().split())))
# x의 범위는 위에서 2칸 이상이어야 한다.
for i in range(n-2):
# y의 범위는 양 사이드에서 1칸씩 안에 있어야한다.
for j in range(1,n-1):
for k in range(1,j+1):
for s in range(1,n-1-i-k):
try:
sub=solution(i,j,k,s,n,population)
#만약 처음으로 solution함수를 돌린 것이라면 sub값을 answer로 할당
if answer==-1:
answer=sub
# 만약 answer값이 sub값보다 클 경우 sub값으로 answer값을 변경
elif answer>sub:
answer=sub
except:
continue
print(answer)
'알고리즘 풀이 > 백준 알고리즘' 카테고리의 다른 글
백준 알고리즘 12100번 2048 풀이 with Python (0) | 2020.02.01 |
---|---|
백준 알고리즘 13458번 시험감독 풀이 with Python (0) | 2020.02.01 |
백준 알고리즘 13460번 구슬탈출 풀이 with Python (0) | 2020.01.16 |
백준 알고리즘 14502번 연구소 풀이 with Python (0) | 2020.01.09 |
백준 알고리즘 14503번 로봇청소기 풀이 with Python (0) | 2020.01.01 |
Comments