문제

입력
출력
예제 입력
예제 출력
문제 분석
IDEA
2차원 배열 1개를 생성한다! bool로만 이루어진 2차원 배열!#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int n;
//Number of Aparts Counter
vector<int> apart;
//is that apart visited?
vector<vector<bool> > visited;
// Direction,Down/Up/Right/Left
int dy[4] = {1, -1, 0, 0};
int dx[4] = {0, 0, 1, -1};
void Count(int * count, int x, int y)
{
//내 위치의 visited가 false면 return
if(!visited[y][x]) return;
//true면 카운트 추가하고 false로 만들어주기(다신 방문 안 하게)
*count += 1;
visited[y][x] = false;
//상/하/좌/우 탐색
for(int i=0; i<4; ++i)
{
if (x + dx[i] >= 0 && x + dx[i] < n && y + dy[i] >= 0 && y + dy[i] < n)
{
int newX = x + dx[i], newY = y + dy[i];
if(visited[newY][newX])
{
Count(count, newX, newY);
}
}
}
}
int main()
{
cin >> n;
// Save Data of 2x2 Apart, pair is [isThereApart] and position of vector
visited.resize(n, vector<bool>(n, false));
for (int i = 0; i < n; ++i)
{
//bool로 0110100 들어오면 이걸 그냥 true로 받아버리기에
//string으로 받은 뒤 char 단위로 쪼갤 예정
string isThereApart;
cin >> isThereApart;
for(int j = 0; j < n; ++j)
{
//3항 연산자로, char == '1' 인 경우만 true 넣어주기
visited[j][i] = (isThereApart[j] == '1')? true : false;
}
}
//생각 할 수록 깊이 탐색이 맞음!
//count, posY, posX 등 넘겨서 진행하기
for(int y = 0; y < n; ++y)
{
for(int x = 0; x < n; ++x)
{
int count = 0;
Count(&count, x, y);
if(count != 0)
{
apart.push_back(count);
}
}
}
//오름차순 정렬
sort(apart.begin(), apart.end());
cout<<apart.size()<<'\n';
for(int i = 0; i < apart.size(); ++i)
{
cout<<apart[i]<<'\n';
}
}
[문제 후기]
우선 소요 시간은 대략 1시간 30분! 중간에 그래프를 깊이 탐색을 쓸지, 너비 탐색을 쓸지 고민을 했다. 그래서 그림을 그려서 고민을 해보았는데..

너비 탐색(BFS)을 한 경우, 갯수 Counting이 위 사진과 같이 4개에서 끝날 수 있겠다는 생각이 들었다.

그래서 깊이 탐색(DFS)을 한다면, 갯수 Counting이 이렇게 생각한 대로 될 것이라 결론지었다.
그래서 깊이 탐색으로 결정, count 횟수를 포인터로 넘기면서 방문한 곳은 true->false로 변경시키면서 탐색을 시켜보았다.
이후 count를 vector apart에 넣어, 그 값을 sorting함으로서 결과를 출력하였다.
중간에 newY = x+dy[i]로 하면서 실수를 하였는데, 그 실수를 찾는데 엄청 오래걸릴 뻔 하였다... ㅠㅠㅠ 다음부터는 주의 또 주의 해야겠다.
뿌듯한 점은 이 판단 근거를 도출해내고, 이것을 내 스스로 힘으로 코드를 짠 그대로 백준 문제를 풀었다는 것!
그리고 DFS와 BFS를 어떤 근거에 의해 어떤 상황에서 써야할지 판단했다는 것이다.
추가로...
C언어로 푼다고 하면 어떻게 접근을 해야할까?
1. Visited의 size를 고정시켜놓는다. visited[25][25] 와 같이, 일정 크기로 고정한다. (총 625)
2. apart 벡터 대신 apart 배열을 선언하고 크기를 313 이상으로 고정한다. (그 이유는 아무리 단지수가 많아도 625의 절반보다 크면 되기 때문)
3. 아파트 push_back 부분 대신 int 등을 활용하여 apart 배열 몇번째 들어갈 지 기록해서 넣어준다.
4. 기록한 길이까지 대소비교를 통해 오름차순 정렬한다. (버블소팅 등 활용)
DFS와 BFS 부분을 좀 덜 헤맸으면 더 빨리 풀 수 있었을 것 같은데, 조금은 아쉬운 기분이다. 그래도 자력으로 풀었으니 좋았으!
'CS 지식 정리 > 코딩테스트 준비' 카테고리의 다른 글
| [백준] 1062. 가르침 (C) (0) | 2025.03.07 |
|---|---|
| [공부] 순열과 조합 (C) (0) | 2025.03.06 |
| [백준] 1038. 감소하는 수 (C) (0) | 2025.03.04 |
| [백준] 2294. 동전 2 (C++) (0) | 2025.01.13 |
| [백준] 2293. 동전 1 (C++) (0) | 2025.01.09 |