https://www.acmicpc.net/problem/2146
풀이
1. 배열을 입력 받을 때 큐에 지도상에 1인 부분들을 저장한다.
2. 다리를 놓을라고 탐색을 할 때 같은 섬에 연결하는 것을 방지하기 위하여 섬 마다 번호를 다르게 바꾸어준다.
3. 배열을 입력 받을 때 사용한 큐로 BFS를 해준다. 이때 테두리만 탐색해주면 되기 때문에 섬의 테두리 마다 BFS를 해주어 가장 작은 값을 출력해준다.
풀이는...간단하다. 구현이 나한테는 길로 복잡해서 그렇지..
제출한 코드
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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | #include <stdio.h> void input(); void Q_reset(); void check_reset(); void map_reset(); int partion(int y, int x, int Num); int map[110][110], check[110][110], n; int map_x[10000], map_y[10000], map_front = -1, map_back = -1; int Q_x[10000], Q_y[10000], Q_front, Q_back, min=999999; int dx[] = { 1,-1,0,0 }; int dy[] = { 0,0,-1,1 }; int main() { map_reset(); input(); while (map_front <= map_back) { int x = map_x[++map_front]; int y = map_y[map_front]; if (map[y + 1][x] == 0 || map[y - 1][x] == 0 || map[y][x + 1] == 0 || map[y][x - 1] == 0)//섬의 테두리 부분이면 BFS { //printf("%d %d\n",y,x); int num = map[y][x]; check_reset(); Q_reset(); Q_x[++Q_back] = x; Q_y[Q_back] = y; //printf("/ %d %d\n", y, x); check[y][x] = 1; while (Q_front <= Q_back) { int xx = Q_x[++Q_front]; int yy = Q_y[Q_front]; //printf("// %d %d\n", yy,xx); for (int i = 0; i < 4; i++) { int xxx = xx + dx[i]; int yyy = yy + dy[i]; if (xxx < 1 || yyy<1 || yyy>n || xxx>n) continue; if (map[yyy][xxx] == 0 && check[yyy][xxx]==0) { //printf("///%d %d\n", yyy,xxx); check[yyy][xxx] = check[yy][xx] + 1; Q_x[++Q_back] = xxx; Q_y[Q_back] = yyy; } if (map[yyy][xxx]!=num&&map[yyy][xxx] != 0 && map[yyy][xxx] != -2) { if (check[yy][xx] -1 < min) { min = check[yy][xx] - 1; } } } } } } printf("%d\n",min); return 0; } int partion(int y, int x, int Num)//섬의 번호를 다르게 만들어준다. { map[y][x] = Num; for (int i = 0; i < 4; i++) { int xx = x + dx[i]; int yy = y + dy[i]; if (xx<1 || yy<1 || yy>n || xx>n || map[yy][xx] != -1) continue; partion(yy, xx, Num); } return 1; } void input()//입력 받는다. { scanf("%d", &n); for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { scanf("%d", &map[i][j]); if (map[i][j]) { map[i][j] = -1; map_x[++map_back] = j; map_y[map_back] = i; } } } int num = 1; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (map[i][j] == -1) { num += partion(i, j, num); } } } } void Q_reset() { Q_front = Q_back = -1; for (int i = 0; i<10000; i++) Q_x[i] = Q_y[i] = 0; } void check_reset() { for (int i = 0; i < 110; i++) { for (int j = 0; j < 110; j++) { check[i][j] = 0; } } } void map_reset() { for (int i = 0; i < 110; i++) for (int j = 0; j < 110; j++) map[i][j] = -2; } | cs |
'SW 업무 관련 > 백준' 카테고리의 다른 글
[BEAKJOON] 풀었던 문제들 복습 - 1편(1000번,1001번,1003번,1008번,1057번) (0) | 2017.09.17 |
---|---|
[BEAKJOON] 2456_나는 학급회장이다_C언어 (0) | 2017.09.10 |
[BEAKJOON] 11559_puyo puyo(뿌요뿌요)_C언어 (0) | 2017.09.08 |
[BEAKJOON] 1251_단어 나누기_C언어 (0) | 2017.09.08 |
[BEAKJOON] 4948_베르트랑 공준_C언어 (0) | 2017.09.03 |