문제에서 설명한 대로 구현해주기만 하면 되는 문제이다.

그러나 속도가 너무 느리게 나오는데 아마 x와 y를 돌아볼 때 선거구를 5개 전부 나오게 하는 인덱스만 골라서 탐색을 할 경우 필요 없는 시간을 줄일 수 있을 것 같다. 깡 구현 문제라 그런지 꼼꼼함이 생명이다. 항상 천천히 읽어보며 주석을 다는 습관을 기르자.

https://github.com/ukjinlee66/BOJ/blob/master/17779.cpp

 

ukjinlee66/BOJ

baekjoon. Contribute to ukjinlee66/BOJ development by creating an account on GitHub.

github.com

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
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
int point_x, point_y;
int res=987654321;
int map[21][21];
int gu[21][21];
int cnt[6];
int dx[] = { 0,0,1,-1 };
int dy[] = { 1,-1,0,0 };
void gucount()
{
    memset(cnt, 0sizeof(cnt));//인구
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            cnt[gu[i][j]] += map[i][j];
    int maxnum =-987654321int minnum = 987654321;
    for (int i = 1; i <= 5; i++)
    {
        maxnum = max(maxnum, cnt[i]);
        minnum = min(minnum, cnt[i]);
    }
    res = min(res, maxnum - minnum);
}
void printgu()
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
            cout << gu[i][j] << " ";
        puts("");
    }
    return;
}
void sol(int x, int y,int d1,int d2)
{
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            gu[i][j] = 0;
    //경계선
    int j1 = y, j2 = y;
    bool flag1 = false, flag2 = false;
    for (int i = x; i <= x + d1 + d2; i++)
    {
        for (int w = j1; w <= j2; w++)
            gu[i][w] = 5;
        if (j1 == y - d1) {
            j1++;
            flag1 = true;
        }
        else if (!flag1)
            j1--;
        else
            j1++;
        if (j2 == y + d2) {
            j2--;
            flag2 = true;
        }
        else if (!flag2)
            j2++;
        else
            j2--;
        
    }
    //선거구 지정.
    for (int i = 1; i < x + d1; i++)
        for (int j = 1; j <= y; j++)
            if(gu[i][j]!=5)
                gu[i][j] = 1;
    for (int i = 1; i <= x + d2; i++)
        for (int j = y + 1; j <= n; j++)
            if (gu[i][j] != 5)
                gu[i][j] = 2;
    for (int i = x + d1; i <= n; i++)
        for (int j = 1; j <= y - d1 + d2; j++)
            if (gu[i][j] != 5)
                gu[i][j] = 3;
    for (int i = x + d2 + 1; i <= n; i++)
        for (int j = y - d1 + d2; j <= n; j++)
            if (gu[i][j] != 5)
                gu[i][j] = 4;
    
    /*printgu();*/
    gucount();
    return;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    /*
        1) x = d1,d2>=1,1<=x<x+d1+d2<=n,
           y = 1<=y-d1<y<y+d2<=n
        경계선
        1-1)(x, y), (x+1, y-1), ..., (x+d1, y-d1)
        1-2)(x, y), (x+1, y+1), ..., (x+d2, y+d2)
        1-3)(x+d1, y-d1), (x+d1+1, y-d1+1), ... (x+d1+d2, y-d1+d2)
        1-4)(x+d2, y+d2), (x+d2+1, y+d2-1), ..., (x+d2+d1, y+d2-d1)
    */
    //2)경계선과 경계선안에 포함된 선거구는 5번.
    /*
        3)5번 선거구에 포함되지 않은 구역 (r, c)의 선거구 번호는 다음 기준을 따른다.
        1번 선거구 : 1 ≤ r < x + d1, 1 ≤ c ≤ y
        2번 선거구 : 1 ≤ r ≤ x + d2, y < c ≤ N
        3번 선거구 : x + d1 ≤ r ≤ N, 1 ≤ c < y - d1 + d2
        4번 선거구 : x + d2 < r ≤ N, y - d1 + d2 ≤ c ≤ N
    */
    //각 점 point_x,point_y 를 돌아보며 d의 크기를 범위만큼 늘려본다 -> 선거구의 최대최소 사이즈를 비교해보고 결과값에 집어넣는다.
    cin >> n;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            cin >> map[i][j];
    for (int x = 1; x <= n; x++
    {
        for (int y = 1; y <= n; y++)
        {
            for (int d1 = 1; d1 <= n; d1++)
            {
                for (int d2 = 1; d2 <= n; d2++)
                {
                    //x,y check d1,d2>=1,1<=x<x+d1+d2<=n , 1<=y-d1<y<y+d2<=n
                    if (x + d1 + d2 <= n)
                        if (y + d2 <= n)
                            sol(x, y, d1, d2);
                }
            }
        }
    }
    cout << res;
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

'Problem Solving > 삼성 역량테스트' 카테고리의 다른 글

BOJ-14500 테트로미노  (0) 2019.11.07
BOJ-17837 새로운 게임2  (0) 2019.11.06
BOJ-12100 2048(Easy)  (0) 2019.11.06
BOJ-17144 미세먼지 안녕  (0) 2019.11.06
BOJ-17780 새로운 게임  (0) 2019.11.05

+ Recent posts