본문 바로가기
알고리즘/나동빈

[삼성기출] 나동빈 - C++ Q16 연구소

by 꾸준하곰 2021. 11. 11.

DFS 문제이다.

 

풀이

모든 좌표를 방문해서, 바이러스를 막기 위한 벽을 설치하자.

 

1) (0, 0) 부터 map 의 빈칸에 벽을 설치한다.

2) 벽 개수 * 3 이라면, 

    2-1) 바이러스 퍼뜨리기

    2-2) 점수 매기기

    2-3) 점수의 max 값을 저장하기

    2-4) return

3) 벽을 설치한 칸을 빈칸으로 바꾼다.

...

Last) (N, M) 까지 map 의 모든 좌표를 방문했을 때 DFS() 는 종료한다.

 

 

1. Solution 코드

#include <iostream>
#include <algorithm>

using namespace std;

int n, m;
int arr[8][8]; // 초기 맵 배열
int temp[8][8]; // 벽을 설치한 뒤의 맵 배열

// 4가지 이동 방향에 대한 배열
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};

int result;

// 깊이 우선 탐색(DFS)을 이용해 각 바이러스가 사방으로 퍼지도록 하기
void virus(int x, int y) {
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i];
        int ny = y + dy[i];
        // 상, 하, 좌, 우 중에서 바이러스가 퍼질 수 있는 경우
        if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
            if (temp[nx][ny] == 0) {
                // 해당 위치에 바이러스 배치하고, 다시 재귀적으로 수행
                temp[nx][ny] = 2;
                virus(nx, ny);
            }
        }
    }
}

// 현재 맵에서 안전 영역의 크기 계산하는 메서드
int getScore() {
    int score = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (temp[i][j] == 0) {
                score += 1;
            }
        }
    }
    return score;
}

// 깊이 우선 탐색(DFS)을 이용해 울타리를 설치하면서, 매 번 안전 영역의 크기 계산
void dfs(int count) {
    // 울타리가 3개 설치된 경우
    if (count == 3) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                temp[i][j] = arr[i][j];
            }
        }
        // 각 바이러스의 위치에서 전파 진행
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (temp[i][j] == 2) {
                    virus(i, j);
                }
            }
        }
        // 안전 영역의 최대값 계산
        result = max(result, getScore());
        return;
    }
    // 빈 공간에 울타리를 설치
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (arr[i][j] == 0) {
                arr[i][j] = 1;
                count += 1;
                dfs(count);
                arr[i][j] = 0;
                count -= 1;
            }
        }
    }
}

int main(void) {
    cin >> n >> m;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> arr[i][j];
        }
    }

    dfs(0);
    cout << result << '\n';
}

 

 

2. 알아야 할 개념

1) 단순 좌표를 이용하고 싶다면, Struct 를 사용하지 말자

// 구조체 사용
struct Point{
	int x, y;
};

// 정수형 자료형 사용
int nx = curx + dx[];
int ny = curx + dy[];

댓글