SWExpertAcademy의 행렬찾기(1258 / D4) 문제이다.


[ 문제풀이 ]

1) 문제를 순서대로 해결해 나가보자.

   가장 먼저 행렬의 갯수를 찾아야 한다. 이 부분을 본인은 너비우선탐색(BFS)로 구현해 보았다.

   탐색의 조건은 다음과 같다. "맵에서 0보다 큰 숫자이면서, 아직 방문하지 않은 좌표" 라면 탐색을 실행해 주었다.

   그렇게 되면, 하나의 정점에서 인접한 숫자들을 순차적으로 탐색하면서 하나의 행렬이 완성될 때 까지 탐색을 진행하게

   될 것이다. 즉, BFS 탐색을 실시하는 횟수가 행렬의 갯수가 되는 것이다.

   두 번째는, BFS를 탐색한 부분(행렬)의 행과 열의 길이를 구해 주었고, 이를 Vector를 하나 선언해 저장해 주었다.

   Vector에서는 총 3개의 값을 관리하였다. { 행의 길이 , 열의 길이 , 넓이 } 이렇게 3개의 값을 저장해 주었다.

   이 후, Vector에 모든 행렬의 { 행의 길이, 열의 길이, 넓이 } 들을 정렬을 사용해서 문제의 조건에 맞게 정렬시켜 주었다.


[ 소스코드 ]

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
134
135
136
137
138
139
140
#include<iostream>
#include<queue>
#include<cstring>
#include<vector>
#include<algorithm>
 
#define endl "\n"
#define MAX 100
using namespace std;
 
int N, Answer;
int MAP[MAX][MAX];
bool Visit[MAX][MAX];
vector<pair<pair<intint>int>> Answer_V;
 
int dx[] = { 001-1 };
int dy[] = { 1-100 };
 
void Initialize()
{
    Answer = 0;
    Answer_V.clear();
    memset(Visit, falsesizeof(Visit));
}
 
void Input()
{
    cin >> N;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            cin >> MAP[i][j];
        }
    }
}
 
void BFS(int a, int b)
{
    queue<pair<intint>> Q;
    Q.push(make_pair(a, b));
    Visit[a][b] = true;
 
    while (Q.empty() == 0)
    {
        int x = Q.front().first;
        int y = Q.front().second;
        Q.pop();
 
        for (int i = 0; i < 4; i++)
        {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (nx >= 0 && ny >= 0 && nx < N && ny < N)
            {
                if (MAP[nx][ny] != 0 && Visit[nx][ny] == false)
                {
                    Visit[nx][ny] = true;
                    Q.push(make_pair(nx, ny));
                }
            }
        }
    }
}
 
void Find_Size(int x, int y)
{
    int Tx = x;
    int Ty = y;
    int Garo, Sero;
    Garo = Sero = 0;
    while (MAP[Tx][y] != 0) { Garo++; Tx++; }
    while (MAP[x][Ty] != 0) { Sero++; Ty++; }
 
    Answer_V.push_back(make_pair(make_pair(Garo, Sero), Garo * Sero));
}
 
bool Standard(pair<pair<intint>int> A, pair<pair<intint>int> B)
{
    if (A.second <= B.second)
    {
        if (A.second == B.second)
        {
            if (A.first.first < B.first.first)
            {
                return true;
            }
            return false;
        }
        return true;
    }
    return false;
}
 
void Solution()
{
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            if (MAP[i][j] != 0 && Visit[i][j] == false)
            {
                BFS(i, j);
                Find_Size(i, j);
                Answer++;
            }
        }
    }
    sort(Answer_V.begin(), Answer_V.end(), Standard);
}
 
void Solve()
{
    int Tc; cin >> Tc;
    for (int T = 1; T <= Tc; T++)
    {
        Initialize();
        Input();
        Solution();
 
        cout << "#" << T << " " << Answer << " ";
        for (int i = 0; i < Answer; i++)
        {
            cout << Answer_V[i].first.first << " " << Answer_V[i].first.second << " ";
        }
        cout << endl;
    }
}
 
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