티스토리 뷰
백준 2573번 빙산입니다. 개인적으로 괜찮게 푼 문제라고 생각하는데.. 다른분들 푼 코드를 보면 뭔가 아쉬운 문제입니다. 이번 문제에서 어려웠던것은 녹을 때 빙산들을 어떻게 처리할 것인가인데요. 저는 따로 지도를 만들어서 그 지도에 그린것들을 다시 복원하는 방법을 선택했어요.
밑에는 제 코드입니다.
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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | #include <iostream> #include <vector> using namespace std; typedef pair<int, int> pos; vector<vector<int>> map; vector<vector<bool>> visited; int dr[4] = { 0,-1,0,1 }; int dc[4] = { -1,0,1,0 }; int N, M; void dfs(pos cur) {//좌표를 받아서 visited[cur.first][cur.second] = true; //방문 체크 for (int i = 0; i < 4; i++) {//4방 탐색 pos next = { cur.first + dr[i],cur.second + dc[i] }; if (map[next.first][next.second] && !visited[next.first][next.second]) { //빙산이 이어져있고, 방문하지 않았다면 dfs(next);//탐색 } } } bool haveIceberg(void) { //빙산이 남아 있는지 체크 for (int r = 0; r < N; r++) { for (int c = 0; c < M; c++) { if (map[r][c]) return true; //있다면 return true; } } return false;//탐색하고도 없다면 return false; } void melt(void) { //원래 지도에서 빙산이 녹아서 체크하려면 //0이되서 바다가되면 주변빙산에 영향을 주기에 //다른 지도를 만들어요 vector<vector<int>> melted = map;//map백업 for (int r = 1; r < N; r++) { for (int c = 1; c < M; c++) { if (map[r][c]) {//원래 지도에 빙산이 있다면 int cnt = 0; for (int i = 0; i < 4; i++) { if (!map[r + dr[i]][c + dc[i]]) cnt++; //주변의 바다 갯수를 세요 } melted[r][c] -= cnt;//다음년도 지도에 표현 if (melted[r][c] < 0) melted[r][c] = 0; //-값이라면 0으로 보정 } } } map = melted;//완성된 다음년도 지도를 그려요 } int icebergCnt(void) { int year = 0; while (true) { int iceberg = 0; for (int r = 1; r < N; r++) { for (int c = 1; c < M; c++) { if (map[r][c] && !visited[r][c]) { //빙산이 있다면 iceberg++;//빙산 갯수++ dfs(pos(r, c));//탐색 } } } if (iceberg > 1) return year; //2개로 쪼개지면 몇년 지났는지 return melt();//그렇지 않으면 빙산이 녹아요 for (int r = 1; r < N; r++) { for (int c = 1; c < M; c++) { //다시 탐색하기위해 방문체크 초기화 visited[r][c] = false; } } if (!haveIceberg()) return 0;//다녹았다면 return 0; year++;//연도++ } } int main(void) { cin >> N >> M; map.resize(N); visited.resize(N); for (int r = 0; r < N; r++) { map[r].resize(M); visited[r].resize(M); for (int c = 0; c < M; c++) { cin >> map[r][c]; } } cout << icebergCnt() << endl; return 0; } | cs |
'Coding > acmicpc' 카테고리의 다른 글
백준 11066:파일 합치기 (0) | 2018.07.18 |
---|---|
백준 1463:1로 만들기 (0) | 2018.05.09 |
백준 2146:다리 만들기 (0) | 2018.04.19 |
백준 5014:스타트링크 (0) | 2018.04.16 |
백준 7576:토마토 (0) | 2018.04.16 |