백준/탐색

[백준] C++ 2638번(치즈)

2zreal 2024. 7. 16. 15:46

 

주어진 치즈가 모두 녹아 없어지는데 걸리는 정확한 시간을 정수로 첫 줄에 출력하는 문제이다.

 

문제 해결 방법

1. 노출된 치즈의 위치를 찾는다

2. 노출된 치즈를 녹인다.

3. 위 과정을 반복한다.

 

그렇다면 노출된 치즈의 위치를 어떻게 판별할까??

노출된 치즈는 4변 중에서 적어도 2변 이상이 실내온도의 공기와 접촉한 것으로 정의되어있다.

즉 치즈가 2번 방문 되어야한다는 말이다.

 

보통은 visited가 0이면 방문을 하고  vistied를 1로 바꾸는데 이 문제에서 나는 vistied가 2 미만이면 방문을 하도록 설정하였다.

공기를 지나가게 되면 vistied를 2로 바꾸고 치즈를 만나면 visited++를 해주어서 노출된 치즈의 위치를 찾았다.

if(arr[num1+row[i]][num2+col[i]]==0)
{
	visited[num1+row[i]][num2+col[i]]=2;
	Q.push(make_pair(num1+row[i],num2+col[i]));
}
else
{
	visited[num1+row[i]][num2+col[i]]++;
	if(visited[num1+row[i]][num2+col[i]]==2)
	{
		arr[num1+row[i]][num2+col[i]]=0;
		count++;			
	}
}

위 과정을 치즈가 다 녹을 때까지 반복해주면 끝난다.

 

#include <iostream>
#include <queue>

using namespace std;

int arr[101][101];
queue <pair<int,int> > Q;
int row[4]={0,0,-1,1};
int col[4]={-1,1,0,0};
int N=0;
int M=0;
int count=0;

void BFS();

int main(void)
{
	
	int sum=0;
	
	cin>>N>>M;
	
	for(int i=0; i<N; i++)
	{
		for(int j=0; j<M; j++)
		{
			cin>>arr[i][j];
			if(arr[i][j]==1)
			{
				sum++;
			}
		}
	}
	
	int page=0;
	
	while(true)
	{
		BFS();
		page++;
		if(count==sum)
		{
			cout<<page;
			break;
		}
	}
	
	return 0;
}

void BFS()
{
	int visited[101][101]={0};
	Q.push(make_pair(0,0));
	
	while(!Q.empty())
	{
		int num1=Q.front().first;
		int num2=Q.front().second;
		Q.pop(); 
		
		for(int i=0; i<4; i++)
		{
			if(visited[num1+row[i]][num2+col[i]]<2&&num1+row[i]>-1&&num1+row[i]<N&&num2+col[i]>-1&&num2+col[i]<M)
			{
				
				if(arr[num1+row[i]][num2+col[i]]==0)
				{
					visited[num1+row[i]][num2+col[i]]=2;
					Q.push(make_pair(num1+row[i],num2+col[i]));
				}
				else
				{
					visited[num1+row[i]][num2+col[i]]++;
					if(visited[num1+row[i]][num2+col[i]]==2)
					{
						arr[num1+row[i]][num2+col[i]]=0;
						count++;	
					}
				}
			}
		}
	}
}