본문 바로가기
코딩테스트 및 개인공부/문제풀이

[백준 - 1926번] [BFS] 그림

by JJPearl 2022. 5. 11.
반응형

그림

시간 제한메모리 제한제출정답맞힌 사람정답 비율
2 초 128 MB 14577 6275 4427 42.074%

문제

어떤 큰 도화지에 그림이 그려져 있을 때, 그 그림의 개수와, 그 그림 중 넓이가 가장 넓은 것의 넓이를 출력하여라. 단, 그림이라는 것은 1로 연결된 것을 한 그림이라고 정의하자. 가로나 세로로 연결된 것은 연결이 된 것이고 대각선으로 연결이 된 것은 떨어진 그림이다. 그림의 넓이란 그림에 포함된 1의 개수이다.

입력

첫째 줄에 도화지의 세로 크기 n(1 ≤ n ≤ 500)과 가로 크기 m(1 ≤ m ≤ 500)이 차례로 주어진다. 두 번째 줄부터 n+1 줄 까지 그림의 정보가 주어진다. (단 그림의 정보는 0과 1이 공백을 두고 주어지며, 0은 색칠이 안된 부분, 1은 색칠이 된 부분을 의미한다)

출력

첫째 줄에는 그림의 개수, 둘째 줄에는 그 중 가장 넓은 그림의 넓이를 출력하여라. 단, 그림이 하나도 없는 경우에는 가장 넓은 그림의 넓이는 0이다.

예제 입력 1 복사

6 5
1 1 0 1 1
0 1 1 0 0
0 0 0 0 0
1 0 1 1 1
0 0 1 1 1
0 0 1 1 1

예제 출력 1 복사

4
9

 


 

풀이 과정

Queue 자료구조로 BFS 구현하여 품.

2차원 vector로 입력을 받는다.

1. pair를 이용해 시작점 좌표를 (0,0)부터 시작 -> *여기도 방문 표시를 해줬어야됨 이것때문에 자꾸 size +1 되서 나왔다

2. 2차원 벡터를 순회하면서 시작점이 될 수 있는 1을 찾는다

3. 찾은 시작점을 큐에 pair로 넣는다.

4. 네 방향을 검사해서 그림인 곳(1)의 좌표를 큐에 넣고 tempSize를 올려준다.

5. 해당 BFS 탐색을 큐가 빌때까지 반복 

6. BFS 순회가 끝나고 tempSize가 가장 큰 크기를 저장하는 변수인 size보다 크다면 size에 저장

-> 문제: 네 방향에 0일땐 continue로 처리하고 그다음 지금 탐색하고 있는 그림의 tempSize를 올려주고,

tempSize가 1이상일 때 count를 올려주므로 그림(1)이 하나일 때 count가 올라가지 않는다.

-> bool값 변수로 큐에 시작점 값이 있는데 네 방향이 막혀 있는 경우를 따로 처리해서 해결

-> 근데 이러면 그림이 없어도 무조건 count와 size가 1이 나옴. 이방법은 아니었다.

=> 시작점 좌표를 큐에 푸쉬하는걸 반복문 안에서 했으면 이런 예외처리 안해줘도 됬음.

=> 7% 오류가 계속 났었는데 출력처리를 newline을 안해줘서 그런거였다. 이것때문에 삽질했다 ㅡㅡ

코드

#include <queue>
#include <vector>
#include <iostream>

#define X first
#define Y second
using namespace std;

int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };



int main()
{
	int w = 0, h = 0, cnt = 0, size = 0;
	cin >> h >> w;
	vector<vector<int>> board(h,vector<int>(w,0));

	for (int i = 0; i < h; ++i)
	{
		for (int j = 0; j < w; ++j)
		{
			cin >> board[i][j];
			
		}
	}
	// 배열을 다 돌아보면서 시작점이 있나 다시 체크
	// x는 행, y는 열

	for (int i = 0; i < h; ++i) {
		for (int j = 0; j < w; ++j) {
			if (board[i][j] == 0) continue;
			++cnt;
			queue<pair<int, int>> Q;
			board[i][j] = 0; // 시작점도 방문표시
			int tempSize = 0;
			//bool isOnlyOne = false;	
			Q.push({ i,j });
			while (!Q.empty()) {
				++tempSize;
				pair<int, int> cur = Q.front();
				Q.pop();
				for (int dir = 0; dir < 4; ++dir)
				{
					int nx = cur.X + dx[dir];
					int ny = cur.Y + dy[dir];
					if (nx < 0 || ny < 0 || nx >= h || ny >= w) continue;
					if (board[nx][ny] != 1) continue;
					board[nx][ny] = 0; // 방문했다
					Q.push(make_pair(nx, ny));
				}
			
			}
			if (size < tempSize)
				size = tempSize;
			
		}
	}
	cout << cnt << '\n' << size;
}

 

 

 

알게된 것

- 2차원 벡터 초기화 방법 : vector<vector<int>> board(h,vector<int>(원소개수,0)); // 원소 0으로 초기화 이런식으로도 가능하다

https://leeeegun.tistory.com/3

 

[C++ STL] 2차원 vector 선언 및 사용법

※ 이 포스팅은 기본적으로 vector에 대한 개념을 알고 있다는 전제하에 작성. 우선 2차원 vector의 선언에 앞서 일반적인 vector 선언을 살펴보면, 1 2 vector  v; v.pushback(7); 위와 같은 형식으로 특정한

leeeegun.tistory.com

 

반응형

'코딩테스트 및 개인공부 > 문제풀이' 카테고리의 다른 글

[백준 - 1874] 스택 수열  (0) 2022.06.15
[백준 - 10773] 제로  (0) 2022.06.15
[백준 - 1158번] 요세푸스 문제  (0) 2022.04.26
[백준 - 5397번] 키로거  (0) 2022.04.26
[백준 - 1406번] 에디터  (0) 2022.04.26