백준의 배열돌리기(16926) 문제이다.

[ 문제 바로가기 ]


[ 문제풀이 ]

1) 문제는 쉽다.. 구현이 생각보다 어려워서 그렇지...

   먼저 몇 개의 좌표에서 사각형을 돌려줘야 되는지 생각해보자.

  

   먼저 위와 같은 예를 한번 봐보도록 하자.

   왼쪽부터 차례대로 맵의 크기가 4x4 , 6x4, 4x6 짜리 맵들이다.

   위의 맵들은 검은점으로 표시된 사각형, 파랑점으로 표시된 사각형 총 2군데에서 배열을 돌려줘야 한다는 것을

   알 수 있다.

  

   그렇다면 위의 맵을 하번 봐보자. 위의 맵에서는 검정, 파랑, 빨강 3개의 사각형을 돌려줘야 한다는 것을 알 수 있다.

   그렇다면 몇 개의 사각형을 돌려야 되는지는 어떻게 구해야 할까 ??

   바로 가로길이와 세로길이 중 더 짧은 변의 길이 / 2이 그 갯수이다.

   다시 첫번째 예로 가보자. 4x6, 6x4, 4x6 공통점이 모두 더 짧은 변의 길이가 '4'라는 것이다. 

   4를 2로 나눠버리면 2가 나오는데, 이 2의 의미는 '2개의 사각형을 돌려야한다' 라는 것을 의미한다.

   그 아래의 사각형을 예로 들면 8x6짜리 사각형이다. 즉, 6 / 2 = 3이 되고, 이는 3개의 사각형을 돌려줘야 한다는 것을

   의미한다.

   그럼 홀수가 나오면 어떻게 할까요 ?? 그럴 리 없다. 왜냐하면 문제의 제한에 주어져 있다.

   두 변의 길이중 더 짧은 길이는 2로 나누어 떨어진다 라고 !

   그럼 그 사각형들의 시작점을 어떻게 구할까?? 본인은 이렇게 계산해주었다.

   가장 왼쪽 위의 점을 (0, 0)으로 봤을 때, (0, 0), (1, 1), (2, 2) .... 이 좌표들이 돌려야 될 사각형의 시작점으로

   잡고 생각해주었다.


   실제로 돌려주는 것은 각 좌표마다 재귀를 통해서 R번 움직일 때 까지 구현해 주었다. 이 과정에서 방향의 개념도

   사용하였다.

   왜냐하면 본인은 4개의 변을 따로따로 돌려주었기 때문이다.

   4개의 변이라고 하는 것은, 돌려야 할 사각형에서 왼쪽 세로 변, 아래쪽 가로변, 오른쪽 세로변, 위쪽 가로변

   이렇게 4개의 변을 의미하는데, 왼쪽 세로변의 첫 진행방향은 남쪽, 아래 가로변의 첫 진행방향은 동쪽,

   오른쪽 세로변의 첫 진행방향은 북쪽, 위쪽 가로변의 첫 진행방향은 서쪽이 된다.

   따라서, 배열의 범위를 벗어나게 되면, 방향을 그때그때 바꿔주면서 총 R번 돌때까지 재귀로 깊게 들어가도록

   구현해 주었다.


[ 소스코드 ]

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
#include<iostream>
 
#define endl "\n"
#define MAX 300
using namespace std;
 
int N, M, R, Rotate_Pos;
int MAP[MAX][MAX], C_MAP[MAX][MAX];
bool Visit[MAX][MAX];
 
void Input()
{
    cin >> N >> M >> R;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < M; j++)
        {
            cin >> MAP[i][j];
        }
    }    
}
 
void DFS(int x, int y, int dir, int r, int Range, int Orig)
{
    if (r == R)
    {
        C_MAP[x][y] = Orig;
        return;
    }
 
    if (dir == 0)        // Move East
    {
        if (y + 1 < M - Range) DFS(x, y + 1, dir, r + 1, Range, Orig);
        else DFS(x - 1, y, 3, r + 1, Range, Orig);    
    }
    else if (dir == 1)    // Move West
    {
        if (y - 1 >= Range) DFS(x, y - 1, dir, r + 1, Range, Orig);
        else DFS(x + 1, y, 2, r + 1, Range, Orig);
    }
    else if (dir == 2)    // Move South
    {
        if (x + 1 < N - Range) DFS(x + 1, y, dir, r + 1, Range, Orig);
        else DFS(x, y + 10, r + 1, Range, Orig);
    }
    else if (dir == 3)    // Else
    {
        if (x - 1 >= Range) DFS(x - 1, y, dir, r + 1, Range, Orig);
        else DFS(x, y - 11, r + 1, Range, Orig);
    }
}
 
void Solution()
{
    if (N > M) Rotate_Pos = M / 2;
    else Rotate_Pos = N / 2;
 
    for (int RP = 0; RP < Rotate_Pos; RP++)
    {
        int x = RP;
        int y = RP;
 
        for (int i = x; i < N - RP; i++)
        {
            if (Visit[i][y] == false)
            {
                DFS(i, y, 20, RP, MAP[i][y]);
                Visit[i][y] = true;
            }
        }
        for (int i = y; i < M - RP; i++)
        {
            if (Visit[N - 1 - RP][i] == false)
            {
                DFS(N - 1 - RP, i, 00, RP, MAP[N - 1 - RP][i]);
                Visit[N - 1 - RP][i] = true;
            }
        }
        for (int i = N - 1 - RP; i >= RP; i--)
        {
            if (Visit[i][M - 1 - RP] == false)
            {
                DFS(i, M - 1 - RP, 30, RP, MAP[i][M - 1 - RP]);
                Visit[i][M - 1 - RP] = true;
            }
        }
        for (int i = M - 1 - RP; i >= RP; i--)
        {
            if (Visit[x][i] == false)
            {
                DFS(x, i, 10, RP, MAP[x][i]);
                Visit[x][i] = true;
            }
        }
    }
    
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < M; j++)
        {
            cout << C_MAP[i][j] << " ";
        }
        cout << endl;
    }
}
 
void Solve()
{
    Input();
    Solution();
}
 
int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
 
    //freopen("Input.txt", "r", stdin);
    Solve();
 
    return 0;
}
 
cs



+ Recent posts