SWExpertAcademy의 등산로조성(1949) 문제이다.
[ 문제풀이 ]
1) 본인은 이 문제를 DFS를 통해서 접근해 보았다. 먼저 기존의 맵에서 갈 수 있는 등산로의 최대길이를 계산해서 값을 한번
갱신시켜 주었고 이후에 모든 좌표들을 돌면서 1부터 K 까지 돌면서 그 값만큼 빼주면서 진행해 주는 완전탐색 방법을
진행해 주었다. 모든 좌표들을 돌면서 다 빼준것 맞지만, 가장 낮은 지형에 대해서는 계산해 주지 않았다.
가장 낮은 지형을 더 낮춰줘봤자 크게 의미가 없는 탐색이기 때문이다.
사실 시간이 조금 걸리는 부분이 있어서 줄여주고 싶었는데 도저히 방법이 생각이 나질 않았따....
2) 사실 DFS탐색은 특별한 조건은 없었다. 이동하려는 봉우리가 이전 봉우리보다 낮기만 하다면 탐색을 계속 진행해주면
된다. 별다른 설명보다는 소스코드만 보더라도 충분히 이해할 수 있을 거라 생각한다.
[ 소스코드 ]
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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | #include<iostream> #include<cstring> #include<vector> #include<queue> #define endl "\n" #define MAX 8 using namespace std; bool Already_Answer; int Answer, N, K; int MAP[MAX][MAX]; bool Visit[MAX][MAX]; int dx[] = { 0, 0, 1, -1 }; int dy[] = { 1, -1, 0, 0 }; vector<pair<int, int>> V_Max; int Bigger(int A, int B) { if (A > B) return A; return B; } int Max, Min; void Initialize() { Answer = 0; Already_Answer = true; Max = 0; Min = 987654321; memset(Visit, false, sizeof(Visit)); memset(MAP, 0, sizeof(MAP)); V_Max.clear(); } void Input() { int Num = 0; cin >> N >> K; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { cin >> MAP[i][j]; if (i == 0 && j == 0) Num = MAP[i][j]; else { if (Already_Answer == true) { if (MAP[i][j] != Num) Already_Answer = false; } } if (MAP[i][j] > Max) Max = MAP[i][j]; if (MAP[i][j] < Min) Min = MAP[i][j]; } } for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (MAP[i][j] == Max) V_Max.push_back(make_pair(i, j)); } } } void BFS(int a, int b, int A[][MAX]) { queue<pair<pair<int, int>, int>> Q; Q.push(make_pair(make_pair(a, b), 1)); Visit[a][b] = true; int Cnt; while (Q.empty() == 0) { int x = Q.front().first.first; int y = Q.front().first.second; Cnt = Q.front().second; Q.pop(); for (int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if (nx >= 0 && ny >= 0 && nx < N && ny < N) { if (Visit[nx][ny] == false && A[nx][ny] < A[x][y]) { Visit[nx][ny] = true; Q.push(make_pair(make_pair(nx, ny), Cnt + 1)); } } } } Answer = Bigger(Answer, Cnt); } void DFS(int x, int y, int Len, int A[][MAX]) { Answer = Bigger(Answer, Len); Visit[x][y] = true; for (int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if (nx >= 0 && ny >= 0 && nx < N && ny < N) { if (Visit[nx][ny] == false && A[nx][ny] < A[x][y]) { DFS(nx, ny, Len + 1, A); } } } Visit[x][y] = false; } void Copy_MAP(int A[][MAX], int B[][MAX]) { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { A[i][j] = B[i][j]; } } } void Solution() { if (Already_Answer == true) { Answer = 2; return; } for (int i = 0; i < V_Max.size(); i++) { int x = V_Max[i].first; int y = V_Max[i].second; DFS(x, y, 1, MAP); } for (int k = 0; k < V_Max.size(); k++) { int x = V_Max[k].first; int y = V_Max[k].second; int C_MAP[MAX][MAX]; Copy_MAP(C_MAP, MAP); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (MAP[i][j] == Min) continue; if (i == x && j == y) continue; for (int t = 1; t <= K; t++) { C_MAP[i][j] = C_MAP[i][j] - t; DFS(x, y, 1, C_MAP); C_MAP[i][j] = C_MAP[i][j] + t; } } } } } void Solve() { int Tc; cin >> Tc; for (int T = 1; T <= Tc; T++) { Initialize(); Input(); Solution(); cout << "#" << T << " " << Answer << endl; } } int main(void) { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); //freopen("Input.txt", "r", stdin); Solve(); return 0; } | cs |
'[ SWEA Code ] > # SWEA - ' 카테고리의 다른 글
[ SWEA 4050 ] 재관이의 대량할인 (C++) (0) | 2019.04.17 |
---|---|
[ SWEA 4672 ] 수진이의 팰린드롬 (C++) (0) | 2019.04.16 |
[ SWEA 2382 ] 미생물 격리 (C++) (0) | 2019.04.12 |
[ SWEA 2115 ] 벌꿀 채취 (C++) (0) | 2019.04.12 |
[ SWEA 2117 ] 홈 방범 서비스 (C++) (0) | 2019.04.11 |