https://www.acmicpc.net/problem/2636
치즈 성공
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞은 사람 | 정답 비율 |
---|---|---|---|---|---|
1 초 | 128 MB | 3247 | 1479 | 1135 | 50.602% |
문제
아래 <그림 1>과 같이 정사각형 칸들로 이루어진 사각형 모양의 판이 있고, 그 위에 얇은 치즈(회색 으로 표시된 부분)가 놓여 있다. 판의 가장자리(<그림 1>에서 네모칸에 엑스친 부분)에는 치즈가 놓여 있지 않으며 치즈에는 하나 이상의 구멍이 있을 수 있다.
이 치즈를 공기 중에 놓으면 녹게 되는데 공기와 접촉된 칸은 한 시간이 지나면 녹아 없어진다. 치즈의 구멍 속에는 공기가 없지만 구멍을 둘러싼 치즈가 녹아서 구멍이 열리면 구멍 속으로 공기가 들어 가게 된다. <그림 1>의 경우, 치즈의 구멍을 둘러싼 치즈는 녹지 않고 ‘c’로 표시된 부분만 한 시간 후 에 녹아 없어져서 <그림 2>와 같이 된다.
다시 한 시간 후에는 <그림 2>에서 ‘c’로 표시된 부분이 녹아 없어져서 <그림 3>과 같이 된다.
<그림 3>은 원래 치즈의 두 시간 후 모양을 나타내고 있으며, 남은 조각들은 한 시간이 더 지나면 모두 녹아 없어진다. 그러므로 처음 치즈가 모두 녹아 없어지는 데는 세 시간이 걸린다. <그림 3>과 같이 치즈가 녹는 과정에서 여러 조각으로 나누어 질 수도 있다.
입력으로 사각형 모양의 판의 크기와 한 조각의 치즈가 판 위에 주어졌을 때, 공기 중에서 치즈가 모두 녹아 없어지는 데 걸리는 시간과 모두 녹기 한 시간 전에 남아있는 치즈조각이 놓여 있는 칸의 개수 를 구하는 프로그램을 작성하시오.
입력
첫째 줄에는 사각형 모양 판의 세로와 가로의 길이가 양의 정수로 주어진다. 세로와 가로의 길이는 최대 100이다. 판의 각 가로줄의 모양이 윗 줄부터 차례로 둘째 줄부터 마지막 줄까지 주어진다. 치즈가 없는 칸은 0, 치즈가 있는 칸은 1로 주어 지며 각 숫자 사이에는 빈칸이 하나씩 있다.
출력
첫째 줄에는 치즈가 모두 녹아서 없어지는 데 걸리는 시간을 출 력하고, 둘째 줄에는 모두 녹기 한 시간 전에 남아있는 치즈조각이 놓여 있는 칸의 개수를 출력한다.
예제 입력 1
13 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 0 1 1 0 0 0 0 1 1 1 1 0 0 1 1 0 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
예제 출력 1
3 5
이전에 풀었던 치즈의 변형판!! 거의 비슷!
(1) 표면부분 out행렬을 계속 갱신하며 표면에 닿는 치즈를 녹여 없애면서 count 한다. ==> answer
(2) 다 치즈가 없어져 0이 되는 경우가 아닐 때에 다 녹기 직전의 치즈 개수를 갱신한다. ==> prev_num
(3) 치즈가 다 녹아 없어져서 한번도 치즈를 녹이지 않을 때 flag로 처리하여 종료한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> int v[101][101] = { 0 }; int dx[4] = { 0,0,-1,1 }; int dy[4] = { 1,-1,0,0 }; int out[101][101] = { 0 }; int flag = 1; int N, M; void dfs(int _x, int _y) { if (out[_x][_y] == 0) { out[_x][_y] = 1;} for (int i = 0; i < 4; i++) { int mx = _x + dx[i]; int my = _y + dy[i]; if (mx >= 0 && mx < N && my >= 0 && my < M && v[mx][my] == 0 && out[mx][my] == 0) { dfs(mx, my); } } return; } int main(void) { int prev_num = 0; int cnt = 0; int answer = 0; int num = 0; scanf("%d %d", &N, &M); for (int i = 0; i < N; i++) for (int j = 0; j < M; j++) { scanf("%d", &v[i][j]); if (v[i][j]) num++; } while (flag) { if(num) prev_num = num; flag = 0; memset(out, 0, sizeof(out)); dfs(0, 0); for (int i = 1; i < N - 1; i++) { for (int j = 1; j < M - 1; j++) { for (int k = 0; k < 4; k++) { int mx = i + dx[k]; int my = j + dy[k]; if (out[mx][my] == 1) cnt++; } if (v[i][j] == 1 && cnt >= 1) { v[i][j] = 0; flag = 1; num--; } cnt = 0; } } answer++; } printf("%d\n%d", answer - 1, prev_num); return 0; } | cs |
'Problem > DFS' 카테고리의 다른 글
[백준알고리즘] 2583번 영역 구하기 (0) | 2018.11.26 |
---|---|
[백준알고리즘] 4963번 섬의 개수 (0) | 2018.11.25 |
[백준알고리즘] 2606번 바이러스 (0) | 2018.11.15 |
[백준알고리즘] 2667번 단지번호붙이기 (0) | 2018.11.05 |
[백준알고리즘] 2638번 치즈 (0) | 2018.11.05 |