백준 2636 c++

magicdrill·2024년 10월 1일
0

백준 문제풀이

목록 보기
452/654

백준 2636 c++

오랜만에 BFS 문제를 풀어보았다.
처음 풀이할 때 포기하고 다시 도전해 본 문제다.
첫 풀이 때는 치즈를 시작으로 BFS를 돌리려 해서 치즈 가운데 구멍을 해결하지 못해서 포기했다.

문제를 다시 잘 읽어보고 배열의 가장자리는 전부 공백으로 치기 때문에 (0,0)에서 BFS를 시작하면 치즈 구멍을 신경 안써도 된다고 생각했다.

풀이 자체는 무난하게 성공했지만, 치즈 개수를 확인 로직을 각 BFS마다 전체 배열을 순회하는 방식으로 해서 불필요한 순회가 많이 발생할거 같았다. 그래서 최초 입력시에 치즈 개수를 받고 (전달된 치즈 개수 - 녹인 치즈 개수)로 다음 치즈 개수를 파악했다.

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

using namespace std;

void input_data(vector<vector<bool>>& cheese, int *init_cheese)
{
	//cout << "\ninput_data()\n";
	int garo, sero, i, j, count = 0;
	bool temp;

	cin >> sero >> garo;
	cheese.resize(sero, vector<bool>(garo));
	for (i = 0; i < sero; i++)
	{
		for (j = 0; j < garo; j++)
		{
			cin >> temp;
			cheese[i][j] = temp;
			if (temp)
			{
				count++;
			}
		}
	}
	*init_cheese = count;

	//cout << "\n입력결과\n";
	//for (i = 0; i < sero; i++)
	//{
	//	for (j = 0; j < garo; j++)
	//	{
	//		cout << cheese[i][j] << " ";
	//	}
	//	cout << "\n";
	//}

	return;
}

void BFS(vector<vector<bool>>& cheese, int *cheese_count, int init_cheese)
{
	//cout << "\nBFS()\n";
	int sero = cheese.size(), garo = cheese[0].size(), count = 0;
	vector<vector<bool>> visited(sero, vector<bool>(garo, 0));
	int i, j, current_x, current_y, next_x, next_y;
	queue <pair<int, int>> q;
	vector<pair<int, int>> direction{ {1, 0},{0, 1},{-1, 0},{0, -1} };

	q.push({ 0, 0 });
	visited[0][0] = true;
	while (!q.empty())
	{
		current_x = q.front().first;
		current_y = q.front().second;
		q.pop();
		for (i = 0; i < direction.size(); i++)
		{
			next_x = current_x + direction[i].first;
			next_y = current_y + direction[i].second;
			if ((next_x >= 0 && next_x < garo) && (next_y >= 0 && next_y < sero) && !visited[next_y][next_x])// 범위 내에 있고, 방문한 적 없음
			{
				if (cheese[next_y][next_x])//치즈인 경우
				{
					cheese[next_y][next_x] = false;//치즈칸 녹이기
					visited[next_y][next_x] = true;//방문 처리
					count++;//녹인 치즈 개수 증가
					//큐에는 안 들어가
				}
				else//빈 공간인 경우
				{
					q.push({ next_x, next_y });//큐에 넣기
					visited[next_y][next_x] = true;//방문하기
					//치즈칸 녹일 필요 없음
				}
			}
		}
	}

	////cout << "치즈 녹이기 BFS() 결과\n";
	//for (i = 0; i < sero; i++)//치즈 개수 확인 //이렇게 하면 매번 순회를 한번 더 하게 되는데...
	//{
	//	for (j = 0; j < garo; j++)
	//	{
	//		if (cheese[i][j])
	//		{
	//			count++;
	//		}
	//		//cout << cheese[i][j] << " ";
	//	}
	//	//cout << "\n";
	//}
	*cheese_count = init_cheese - count;//최초 치즈 개수 - 녹인 치즈 개수 = 현재 남은 치즈 개수

	return;
}

void find_answer(vector<vector<bool>>& cheese, int init_cheese)
{
	//cout << "\nfind_anwser()\n";
	int time_count = 0;//모두 녹아서 없어지는 데 걸리는 시간
	int cheese_count;//모두 녹기 한 시간 전 남은 치즈칸 개수
	//int remained_cheese = init_cheese; //이전 치즈 칸 개수 저장

	while (1)
	{
		BFS(cheese, &cheese_count, init_cheese);
		if (cheese_count == 0)//이번 순회로 치즈가 다 녹아 사라지면?
		{
			time_count++;
			break;
		}
		else//이번 순회 후에도 치즈가 남아 있다면
		{
			init_cheese = cheese_count;
			time_count++;
		}
		//cout << "cheese_count : " << cheese_count << "\n";
		//cout << "remained_cheese : " << remained_cheese << "\n";
		//cout << "time_count : " << time_count << "\n";
	}
	cout << time_count << "\n" << init_cheese << "\n";

	return;
}

int main(void)
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	vector<vector<bool>> cheese;
	int init_cheese = 0;

	input_data(cheese, &init_cheese);
	find_answer(cheese, init_cheese);

	return 0;
}

0개의 댓글