14620 꽃길이랑 정답률 비슷하길래 쉬운줄 알았는데 풀었더니...후...어렵다.
접근 법.
1. O로 표시되어 있는 곳들의 모든 움직임을 탐색한 후에, O가 최소가 될 때의 움직임 횟수를 구하면 된다.
그럼 어떻게 모든 움직임을 탐색할 수 있을까??
반복문으로 O가 있으면 그냥 백트랙킹으로 움직였다. 빽 했다를 반복하면 된다! 이렇게 모든 O에 대해 탐색해보면 정답이 나온다.
기존의 재귀와는 다르게 딱히 재귀의 종료 기준이라 해야되나, 갑자기 생각이 안 나는데. 조건에서 벗어나면 재귀 그만 들어가게 하는 그런 조건문이 없는 것 같다. 아마도.....
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 138 139 140 141 | #include <stdio.h> #include <string.h> int dx[] = { 0,0,-1,1 }, dy[] = { -1,1,0,0 }; int MOVE_MIN, COUNT_MIN; int Check(char arr[5][10]) { int count = 0; for (int i = 0; i < 5; i++) { for (int j = 0; j < 9; j++) { if (arr[i][j] == 'o') count++; } } return count; } int DFS(char map[5][10], int n) { char copy[5][10]; int MIN; //printf("\n"); for (int i = 0; i < 5; i++) { for (int j = 0; j < 9; j++) { copy[i][j] = map[i][j]; //printf("%c", copy[i][j]); } //printf("\n"); } for (int a = 0; a < 5; a++) { for (int j = 0; j < 9; j++) { if (copy[a][j] == '.' || copy[a][j] == '#') continue; int y = a; int x = j; //printf("y : %d x : %d \n", y, x); for (int i = 0; i < 4; i++) { int yy = y + dy[i]; int xx = x + dx[i]; if (yy > 5 || yy < 0 || xx > 9 || xx < 0) continue; if (copy[yy][xx] == 'o') { //printf("yy : %d xx : %d \n", yy, xx); switch (i) { case 0://상 if (yy - 1 >= 0 && copy[yy - 1][xx] == '.') { //printf("상\n"); copy[yy - 1][xx] = 'o'; copy[yy][xx] = copy[y][x] = '.'; DFS(copy, n + 1); copy[yy - 1][xx] = '.'; copy[yy][xx] = copy[y][x] = 'o'; } break; case 1://하 if (yy + 1 < 5 && copy[yy + 1][xx] == '.') { //printf("하\n"); copy[yy + 1][xx] = 'o'; copy[yy][xx] = copy[y][x] = '.'; DFS(copy, n + 1); copy[yy + 1][xx] = '.'; copy[yy][xx] = copy[y][x] = 'o'; } break; case 2://좌 if (xx - 1 >= 0 && copy[yy][xx - 1] == '.') { //printf("좌\n"); copy[yy][xx - 1] = 'o'; copy[yy][xx] = copy[y][x] = '.'; DFS(copy, n + 1); copy[yy][xx - 1] = '.'; copy[yy][xx] = copy[y][x] = 'o'; } break; case 3://우 if (xx + 1 < 9 && copy[yy][xx + 1] == '.') { //printf("우\n"); copy[yy][xx + 1] = 'o'; copy[yy][xx] = copy[y][x] = '.'; DFS(copy, n + 1); copy[yy][xx + 1] = '.'; copy[yy][xx] = copy[y][x] = 'o'; } break; } } } } } MIN = Check(copy); if (MIN < COUNT_MIN) { COUNT_MIN = MIN; MOVE_MIN = n; } return; } int main() { int Test_Case; scanf("%d", &Test_Case); for (int T = 1; T <= Test_Case; T++) { int count = 0; char arr[5][10] = { NULL }; MOVE_MIN = COUNT_MIN = 987654321; for (int i = 0; i < 5; i++) scanf("%s", arr[i]); DFS(arr, 0); printf("%d %d\n", COUNT_MIN, MOVE_MIN); } return 0; } | cs |
'SW 업무 관련 > 백준' 카테고리의 다른 글
[C언어] 14500 테트로미노 (404) | 2018.10.14 |
---|---|
[C언어] 14501. 퇴사 (0) | 2018.10.09 |
[C언어]14620 꽃길 (0) | 2018.10.01 |
[C언어] 15683. 감시 (0) | 2018.09.26 |
[C언어] 3108. 로고 (0) | 2018.09.26 |