Min:D's Devlog

[SWEA][모의 SW 역량테스트][C++] 1949 등산로 조성 본문

알고리즘/SWEA

[SWEA][모의 SW 역량테스트][C++] 1949 등산로 조성

Min:D 2020. 8. 5. 12:00

문제

SWEA 모의 SW 역량테스트 - 1949 등산로 조성

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com


문제 풀이

접근 방식

가장 높은 봉우리에서 시작하여 가장 긴 등산로를 조성하는 문제이다.

등산로를 조성하기 위해서는 상하좌우 네 방향을 탐색하여 이전의 높이보다 낮은 곳으로만 연결해야하고,

딱 한번 산의 높이를 깎는 공사를 할 수 있다.

 

우선, 입력을 받으며 가장 높은 봉우리의 위치를 찾아 highest에 넣어주었다.

그 다음, 그 위치들에서부터 DFS 탐색을 시작하여 가장 긴 등산로를 찾아주었다.

DFS 탐색을 위해 DFS 함수를 만들어주었고, visit 벡터를 활용하여 모든 경우를 탐색해주었다.

DFS 함수위치(x, y)와 등산로의 길이(cnt), 공사 여부(check)를 매개변수로 갖도록 하였다.

 

공사를 하지 않아도 갈 수 있는 경우에는

매개변수에 위치(nx, ny)와 cnt+1, check를 넣어 DFS 함수를 재귀적으로 수행하도록 하였다.

공사를 해야만 갈 수 있고 공사를 아직 안한 상태인 경우(check가 false인 경우)에는

map[nx][ny]의 값을 (현재 높이 - 1)로 설정해주고,

DFS(nx, ny, cnt+1, !check) 실행 후 map[nx][ny]의 값을 다시 원래대로 돌려놓아주었다.

(처음에는 map[nx][ny]의 값을 now - K의 값으로 설정했었는데, 그렇게 하면 now-1로 설정했을 때보다 갈 수 있는 곳이 적어져서 최선이 아니기 때문에 모든 테스트 케이스를 통과할 수 없다.)

최종적으로 이동을 마치면 answer과 cnt값을 비교하여, answer에 최댓값이 저장될 수 있도록 하였다.

 


풀이 코드 - C++

#include <iostream>
#include <vector>
using namespace std;
 
vector<vector<int>> map;
vector<vector<int>> visit;
int N, K, answer;
int dirs[4][2] = { {-1,0},{0,1},{1,0},{0,-1} };
 
void DFS(int x, int y, int cnt, bool check) {
    int nx, ny;
    int now = map[x][y];
    for (int i = 0; i < 4; i++) {
        nx = x + dirs[i][0];
        ny = y + dirs[i][1];
 
        if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;
        if (visit[nx][ny]) continue;
 
        if (now > map[nx][ny]) {
            visit[nx][ny] = 1;
            DFS(nx, ny, cnt + 1, check);
            visit[nx][ny] = 0;
        }
        else if (!check && now > map[nx][ny] - K) {
            visit[nx][ny] = 1;
            int temp = map[nx][ny];
            map[nx][ny] = now - 1;
            DFS(nx, ny, cnt + 1, !check);
            map[nx][ny] = temp;
            visit[nx][ny] = 0;
        }
        else {
            if (answer < cnt)
                answer = cnt;
        }
    }
}
 
int main(int argc, char** argv) {
    int test_case;
    int T, MAX;
    cin >> T;
    for (test_case = 1; test_case <= T; ++test_case) {
        // 입력 받기 & 가장 높은 봉우리 찾기
        cin >> N >> K;
        map.assign(N, vector<int>(N));
        visit.assign(N, vector<int>(N));
        vector<pair<int, int>> highest;
        MAX = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                cin >> map[i][j];
                if (MAX < map[i][j]) {
                    MAX = map[i][j];
                    highest.clear();
                    highest.push_back({ i,j });
                }
                else if (MAX == map[i][j]){
                    highest.push_back({ i,j });
                }
            }
        }
 
        // 가장 긴 등산로 찾기
        answer = 1;
        for (auto i : highest) {
            bool check = false;
            visit[i.first][i.second] = 1;
            DFS(i.first, i.second, 1, check);
            visit[i.first][i.second] = 0;
        }
        cout << "#" << test_case << " " << answer << endl;
    }
    return 0;
}

실행 결과

 

 

 

 

 

Comments