로봇청소기도 어려웠는데 이 문제도 어려웠다. 초등부문제라니 정말..^^
풀이과정을 머릿속으로 떠올려보니,
1) while문을 돌리는데 종료조건은
2) initial함수: visit배열은 사이클을 돌 때마다 초기화해줘야 한다.
3) outAir함수: 외부공기와 내부공기를 구분해줘야 하는데 이는 dfs를 0,0칸에서 돌려주면 자동으로 구분된다. 그 이유는 치즈에 맞닿아있으면 dfs가 탐색을 못하기 때문에 자동으로 못들어간다. 외부공기를 새로운 visit배열에 표시를 해주었다.
4) melt함수: 모든 위치를 돌며 그 위치의 동서남북에서 visit배열의 표시가 하나라도 있으면 외부공기와 맞닿은 부분이 된다. 그래서 이부분을 녹이고, 기존 치즈 갯수에서 1을 빼준다.
5) 출력 만들기: 시간같은 경우 while문 한 cycle을 돌 때마다 1씩 증가시켰고 치즈갯수는 사이클돌면서 업데이트를 해주는데 종료조건을 만날 때는 업데이트가 되지 않아야하기 때문에 종료조건 이후 업데이트 시켰다.
#include<iostream>
#include<cstring>
using namespace std;
int N, M;
int nCheeze = 0;
int map[101][101] = { 0 };
int visit[101][101] = { 0 };
int dx[] = { 1,0,0,-1 };
int dy[] = { 0,1,-1,0 };
void input() {
cin >> N >> M;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
cin >> map[i][j];
if (map[i][j] == 1) nCheeze++;
}
}
}
void init() {
memset(visit, 0, sizeof(visit));
}
void outAir(int x, int y) {
if (visit[x][y] == 0)visit[x][y] = 1;
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
if (map[nx][ny] == 0 && visit[nx][ny] == 0) outAir(nx, ny);
}
return;
}
void melt() {
//테두리는 탐색할 필요가 음슴
for (int i = 1; i < N - 1; i++) {
for (int j = 1; j < M - 1; j++) {
for (int k = 0; k < 4; k++) {
int nx = i + dx[k];
int ny = j + dy[k];
if (visit[nx][ny] == 1) {
if (map[i][j] == 1) {
map[i][j] = 0;
nCheeze--;
break;
}
}
}
}
}
}
int main() {
int time = 0;
int final_cheeze = 0;
input();
while (1) {
final_cheeze = nCheeze;
init();
outAir(0, 0);
melt();
time++;
if (nCheeze == 0)break;
}
cout << time << "\n";
cout << final_cheeze;
}
'Programming > BOJ' 카테고리의 다른 글
[백준/C++] 14502번: 연구소 (0) | 2020.09.07 |
---|---|
[백준/C++] 2589번: 보물섬 (0) | 2020.09.04 |
[백준/C++] 9205번: 맥주 마시면서 걸어가기 (0) | 2020.09.03 |
[백준/C++] 5014번: 스타트링크 (0) | 2020.09.01 |
[백준/C++] 2468번: 안전영역 (1) | 2020.09.01 |