상세 컨텐츠

본문 제목

파이썬으로 풀어보는 백준 17779번: 게리맨더링 2 (삼성 A형 기출 문제)

Python/문제풀이 (삼성 A형 대비)

by 코딩하는 낙타 2020. 2. 7. 19:35

본문

https://www.acmicpc.net/problem/17779

 

17779번: 게리맨더링 2

재현시의 시장 구재현은 지난 몇 년간 게리맨더링을 통해서 자신의 당에게 유리하게 선거구를 획정했다. 견제할 권력이 없어진 구재현은 권력을 매우 부당하게 행사했고, 심지어는 시의 이름도 재현시로 변경했다. 이번 선거에서는 최대한 공평하게 선거구를 획정하려고 한다. 재현시는 크기가 N×N인 격자로 나타낼 수 있다. 격자의 각 칸은 구역을 의미하고, r행 c열에 있는 구역은 (r, c)로 나타낼 수 있다. 구역을 다섯 개의 선거구로 나눠야 하고, 각 구역은 다

www.acmicpc.net

 

내 풀이:

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
29
= int(input())
arr = [list(map(int,input().split())) for _ in range(N)]
 
result = []
for i in range(N):
    for j in range(N):
        for d1 in range(1, min(j, N-i-1)+1):
            for d2 in range(1, min(N-j-1, N-i-1)+1):
                if i + d1 + d2 <= N-1:
                    value1 = 0
                    value2 = 0
                    value3 = 0
                    value4 = 0
                    value5 = 0
                    for a in range(N):
                        for b in range(N):
                            if i+<= a+<= i+j+2*d2 and i-<= a-<= i-j+2*d1:
                                value5 += arr[a][b]
                            elif 0 <= a < i+d1 and 0 <= b <= j and a+< i+j:
                                value1 += arr[a][b]
                            elif 0 <= a <= i+d2 and j < b <= N-1 and a-< i-j:
                                value2 += arr[a][b]
                            elif i+d1 <= a <= N-1 and 0 <= b < j - d1 + d2 and a-> i-j+2*d1:
                                value3 += arr[a][b]
                            elif i+d2 < a <= N-1 and j-d1+d2 <= b <= N-1 and a+> i+j+2*d2:
                                value4 += arr[a][b]
                    result.append(max(value1, value2, value3, value4, value5) - min(value1, value2, value3, value4, value5))
 
print(min(result))
 

Python3, 3840ms

문제의 조건을 그대로 구현하면 풀 수 있는데 문제에서 주는 x, y 좌표가 반대로 돼있고 문제에서 준 기준 역시 반대로 돼있어서 문제를 잘못 이해해서 호되게 혼난 문제이다. 평행사변형 가운데인 5번 구역을 처리해주는 게 까다로운 문제였는데 수학에서 좌표계를 이용하여 문제를 풀 듯이 조건문을 짜서 구현하였다.

 

 

blpoms님 풀이:

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
= int(input())
arr = [[*map(int, input().split())] for _ in range(n)]
ans = 987654321
for d1 in range(1, n - 1):
    for d2 in range(1, n - 1):
        if d1 + d2 >= n: break
        for x in range(n - d1 - d2):
            for y in range(d1, n - d2):
                l = [0* 5
                l[4+= arr[x][y]
                l[0+= sum([sum(arr[i][:y + 1]) for i in range(x)])
                l[1+= sum([sum(arr[i][y + 1:]) for i in range(x)])
                l[0+= sum(arr[x][:y])
                l[1+= sum(arr[x][y + 1:])
                _x_, _y, y_ = x, y, y
                if d1 == d2:
                    for _ in range(d1-1):
                        _x_, _y, y_ = _x_+1, _y - 1, y_ + 1
                        l[0+= sum(arr[_x_][:_y])
                        l[4+= sum(arr[_x_][_y:y_+1])
                        l[1+= sum(arr[_x_][y_+1:])
                    _x_, _y, y_ = _x_ + 1, _y - 1, y_ + 1
                    l[2+= sum(arr[_x_][:_y])
                    l[4+= sum(arr[_x_][_y:y_+1])
                    l[1+= sum(arr[_x_][y_+1:])
                    for _ in range(d1):
                        _x_, _y, y_ = _x_ + 1, _y + 1, y_ - 1
                        l[2+= sum(arr[_x_][:_y])
                        l[4+= sum(arr[_x_][_y:y_ + 1])
                        l[3+= sum(arr[_x_][y_+1:])
                elif d1 < d2:
                    for _ in range(d1-1):
                        _x_, _y, y_ = _x_ + 1, _y - 1, y_ + 1
                        l[0+= sum(arr[_x_][:_y])
                        l[4+= sum(arr[_x_][_y:y_ + 1])
                        l[1+= sum(arr[_x_][y_ + 1:])
                    _x_, _y, y_ = _x_ + 1, _y - 1, y_ + 1
                    l[2+= sum(arr[_x_][:_y])
                    l[4+= sum(arr[_x_][_y:y_ + 1])
                    l[1+= sum(arr[_x_][y_ + 1:])
                    for _ in range(d2-d1-1):
                        _x_, _y, y_ = _x_ + 1, _y + 1, y_ + 1
                        l[2+= sum(arr[_x_][:_y])
                        l[4+= sum(arr[_x_][_y:y_ + 1])
                        l[1+= sum(arr[_x_][y_ + 1:])
                    for _ in range(d1):
                        _x_, _y, y_ = _x_ + 1, _y + 1, y_ - 1
                        l[2+= sum(arr[_x_][:_y])
                        l[4+= sum(arr[_x_][_y:y_ + 1])
                        l[3+= sum(arr[_x_][y_ + 1:])
                else:
                    for _ in range(d2):
                        _x_, _y, y_ = _x_ + 1, _y - 1, y_ + 1
                        l[0+= sum(arr[_x_][:_y])
                        l[4+= sum(arr[_x_][_y:y_ + 1])
                        l[1+= sum(arr[_x_][y_ + 1:])
                    for _ in range(d1-d2-1):
                        _x_, _y, y_ = _x_ + 1, _y - 1, y_ - 1
                        l[0+= sum(arr[_x_][:_y])
                        l[4+= sum(arr[_x_][_y:y_ + 1])
                        l[3+= sum(arr[_x_][y_ + 1:])
                    _x_, _y, y_ = _x_ + 1, _y - 1, y_ - 1
                    l[2+= sum(arr[_x_][:_y])
                    l[4+= sum(arr[_x_][_y:y_ + 1])
                    l[3+= sum(arr[_x_][y_ + 1:])
                    for _ in range(d2):
                        _x_, _y, y_ = _x_ + 1, _y + 1, y_ - 1
                        l[2+= sum(arr[_x_][:_y])
                        l[4+= sum(arr[_x_][_y:y_ + 1])
                        l[3+= sum(arr[_x_][y_ + 1:])
                l[2+= sum([sum(arr[i][:_y]) for i in range(_x_ + 1, n)])
                l[3+= sum([sum(arr[i][y_:]) for i in range(_x_ + 1, n)])
                ans = min(ans, max(l) - min(l))
print(ans)
 

Python3, 352ms

d1과 d2의 관계에 따라서 어느 구역에 더해야하는 값인지를 판단하여 arr를 한 바퀴만 돌아도 문제를 풀 수 있도록 구현한 것 같다. 다만 이와 같은 풀이는 문제를 해석하는 데 시간이 오래 소요될 것으로 예상되며 코딩 길이도 내 코드의 3배가량이다.

관련글 더보기

댓글 영역