문제출처 : https://www.acmicpc.net/problem/2573


1. 문제요약

- 물과 상하좌우 4방향으로 인접한 빙하는 접하는 면 갯수 만큼 1년 뒤 녹음

- 빙하가 두 덩어리 이상으로 분리되는 최초시간

- 빙하가 다 녹을 때 까지 두 덩어리 이상으로 분리되지 않는다면 0 출력

- 3 <= 행n, 열m <= 300

- 첫행, n-1행, 첫열, m-1열은 0으로 주어짐

- 빙하의 최대 갯수는 10,000 이하


2. 접근방법

- 빙하 갯수를 세는 dfs or bfs

- 맵을 돌면서 물이 접하고 있는 빙하를 -1


3. 시간복잡도

- 빙하 갯수를 세는 dfs : N*M

- 맵을 돌면서 물이 접하고 있는 빙하 -1 : N*M

  => 여기까지 2NM


- 위 두 과정을 최대 몇번이나 반복할까?

  빙하의 갯수는 최대 10000 = 25 * 40

  행 25, 열 40 으로 된 한 덩어리의 빙하가 가장 늦게 녹음. 물과 접하는 면이 가장 작기 때문(50 + 80)

  정중앙에 있는 빙하가 가장 늦게 녹을 텐데 여기까지 도달하기 위해서는 12행((25 - 1) / 2)이 녹아야함

  모든 빙하가 10이라고 한다면 대략 한 행이 녹는데 10년

  12행이 녹는데 120년

  => 120 * 2NM = 21,600,000 반복

  => 반복마다 코드 길이가 조금 되지만 시간내엔 들어옴


4. 회고

- dfs를 돌때 4방향 탐색을

  if(!map[r-1][c] && !check[r-1][c]) dfs(r-1, c);

  if(!map[r][c-1] && !check[r][c-1]) dfs(r, c-1);

  if(!map[r+1][c] && !check[r+1][c]) dfs(r+1, c);

  if(!map[r][c+1] && !check[r][c+1]) dfs(r, c+1);

  은 틀리고


  for(int k = 0; k < 4; k++){

int nr = r + dr[k];

int nc = c + dc[k];


if(!map[nr][nc] && !check[nr][nc])

dfs(nr, nc);

  }

  는 맞는거지??


  물론 중간에 빙하 깍는 과정을 조금 수정했지만 디버깅 하면서 둘다 잘 돌아갔는데

  으흠.... 

  한시간동안 뻘짓했는데


- 시간이 244ms 나왔는데 더 줄일 수는 없을까?

- dfs에서 2개 이상 발견하면 dfs 안돌고 탈출

- 다 녹은 빙하 위치를 기억해서 다음 시작점을 거기서 부터 녹여나가도



소스코드



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 11726 2xn 타일링  (0) 2018.01.12
BOJ 1463 1로 만들기  (0) 2018.01.12
BOJ 1389 케빈 베이컨의 6단계 법칙  (0) 2018.01.04
BOJ 9205 맥주 마시면서 걸어가기  (0) 2018.01.03
BOJ 1325 효율적인 해킹  (0) 2017.12.27

+ Recent posts