개발/자료구조, 알고리즘

[코딩 테스트] 소프티어 연습 문제 - 장애물 인식 프로그램 (C++)

growing-dev 2023. 6. 5. 10:38
반응형

오늘은 소프티어 연습문제 중 level 장애물 인식프로그램 문제를 풀어보았습니다.

 

 

 

소프티어 연습 문제 - 장애물 인식 프로그램 

 

 

https://softeer.ai/practice/info.do?idx=1&eid=409&sw_prbl_sbms_sn=212619 

 

Softeer

연습문제를 담을 Set을 선택해주세요. 취소 확인

softeer.ai

 

 

 문제 설명

 

 

자율주행팀 SW 엔지니어인 당신에게 장애물과 도로를 인식할 수 있는 프로그램을 만들라는 업무가 주어졌다.

 

[그림 1] 지도 예시

 

우선 [그림 1]과 같이 정사각형 모양의 지도가 있다. 1은 장애물이 있는 곳을, 0은 도로가 있는 곳을 나타낸다.

 

당신은 이 지도를 가지고 연결된 장애물들의 모임인 블록을 정의하고, 불록에 번호를 붙이려 한다. 여기서 연결되었다는 것은 어떤 장애물이 좌우, 혹은 아래위로 붙어 있는 경우를 말한다. 대각선 상에 장애물이 있는 경우는 연결된 것이 아니다.

 

 

[그림 2] 블록 별 번호 부여

 

[그림 2]는 [그림 1]을 블록 별로 번호를 붙인 것이다. 

 

지도를 입력하여 장애물 블록수를 출력하고, 각 블록에 속하는 장애물의 수를 오름차순으로 정렬하여 출력하는 프로그램을 작성하시오.

 

 

 

 

 제약 사항

 

N은 정사각형임으로 가로와 세로의 크기는 같으며 5 ≤ N ≤ 25

 

 

 입출력 예제

 

입력예제1
7
1110111
0110101
0110101
0000100
0110000
0111110
0110000
출력예제1
3
7
8
9

 

 

 

 코드

 

저는 dfs를 활용하여 풀었습니다. dfs를 활용하는 전형적인 문제 중 하나인 2차원 배열을 탐색하는 문제였습니다.

한 가지 주의할 사항은, 최초 map 입력을 받을 때 한 줄 단위로 들어오는 것을 처리하는 문제였습니다.

다른 방식으로 처리하다가 계속 답안이 맞지 않아서 결국 검색을 통해 입력값만 참고하였습니다.

 

상대적으로 dfs 문제 같은 경우는 답이 한번 맞으면 웬만하면 정답인 경우가 많습니다. 따라서 다른 부가적인 곳에서의 버그나 실수를 찾는 것이 좋은 것 같습니다.

 

좀 더 개선한다면 전역 변수들을 지역 변수화 해서 깔끔하게 만들어 보고 싶습니다. 또 bfs로 푸는 연습도 하면 좋을 것 같습니다.

 

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
const int MAX = 25;
int dx[] = { -1, 1, 0, 0 };
int dy[] = { 0, 0, -1, 1 };

int N;
int map[MAX][MAX];
int check[MAX][MAX];
vector<int> answer;
int cnt = 0;

void dfs(int x, int y)
{
	check[x][y] = 1;
	cnt++;
	for (int i = 0; i < 4; i++)
	{
		int xx = x + dx[i];
		int yy = y + dy[i];
		if (xx < 0 || xx >= N || yy < 0 || yy >= N || map[xx][yy] == 0) continue;
		if (check[xx][yy] == 0)
		{
			check[xx][yy] = 1;
			
			dfs(xx, yy);
		}
	}
}

int main()
{
	cin >> N;
	for (int i = 0; i < N; i++)
	{
		for (int j = N - 1; j >= 0; j--)
		{
			scanf("%01d", &map[i][j]);
		}
	}

	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			if (check[i][j] != 0 || map[i][j] == 0) continue;
			
			cnt = 0;
			dfs(i, j);
			answer.push_back(cnt);
		}
	}


	sort(answer.begin(), answer.end());

	cout << answer.size() << endl;

	for (auto const& block : answer)
	{
		cout << block << endl;
	}
}

 

 

 

 

 

 결론

 

dfs를 활용한 전형적인 문제였습니다. 오랜만에 dfs를 풀어보다보니 시간이 다소 걸리긴 했고 또 입력을 받는 것에 실수를 하긴 했지만 상대적으로 쉽게 풀 수 있었던 문제였습니다.

반응형