[백준] 17141번 연구소 2 (C++)

2025. 8. 7. 23:48·Algorithm
728x90

https://www.acmicpc.net/problem/17141

 

 

이 문제는 격자가 주어지고 바이러스를 놓을 수 있는 위치가 주어질때 어느곳에 바이러스를 M개만큼 둬야 최소 시간동안

모든 격자에 바이러스가 다 퍼지는지 알아내는 문제이다.

 

바이러스를 놓을 수 있는 위치가 주어졌을때 그 위치에 놓는것이 최적인지 확인이 불가하기 때문에

모든 경우의 수를 구해야한다. 즉 바이러스를 놓을 수 있는 위치를 x라고 두고

놓을 수 있는 개수를 y라고 했을때

 

x \times y 로 표현할 수 있다.

 

 

1. 백트래킹으로 나올 수 있는 경우의 수를 구한다.

2. 이후 놓았던 바이러스를 시간이 지남에 따라 확장시킨다(bfs)

3. 이때 다 확장됬을 경우 최소 시간을 업데이트 한다.

 

이때 중요한 것은 바이러스를 퍼뜨리기 위한 새로운 배열을 하나 만들어야 하며 방문했는지 아닌지에 대한 배열을 따로 추가해야한다.

 

정답 코드

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
#define endl "\n"
#define MAX 1e9

struct coordinate {
    int x;
    int y;
};

int dx[] = {-1, 0, 1, 0, 1, -1, -1, 1};
int dy[] = {0, 1, 0, -1, -1, 1, -1, 1};
int N, M;
int graph[51][51];      // 0 : 빈칸, 1 : 벽, 2 : 바이러를 놓을 수 있는 칸
int C_Map[51][51];
vector<coordinate> virus;
bool visited[10];
bool check[51][51];
int result = MAX;
int tmpcnt;

void Copy() {			// 바이러스를 놓을 임시 배열 복사
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++) {
            C_Map[i][j] = graph[i][j];
            check[i][j] = false;
        }
    }
}

void Spread() {			// 바이러스 퍼트리기
    vector<coordinate> tmp;

    for(int i = 0; i < virus.size(); i++) {
        if(visited[i]) {
            tmp.push_back({virus[i]});
        }
    }

    int cnt = 0;

    for(auto it : tmp) {
        int x = it.x;
        int y = it.y;

        check[x][y] = true;
    }
    while(!tmp.empty()) {
        vector<coordinate> tmparr;
        for(auto it: tmp) {
            int x = it.x;
            int y = it.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 >= N) continue;

                if(C_Map[nx][ny] != 1 && !check[nx][ny]) {
                    tmparr.push_back({nx, ny});
                    check[nx][ny] = true;
                }
            }
        }
        tmp = tmparr;
        cnt++;
    }

    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++) {
            if(C_Map[i][j] != 1 && !check[i][j]) {
                return;
            }
        }
    }

    result = min(result, cnt);
}

void bt(int x, int cnt) {			// 바이러스를 놓을 수 있는 조합 구하기
    if(cnt == M) {
        Copy();
        Spread();
        return;
    }

    for(int i = x; i < virus.size(); i++) {
        if(!visited[i]) {
            visited[i] = true;
            bt(i+1, cnt+1);
            visited[i] = false;
        }
    }
}

void solve() {
    if(M == 0) {
        if(tmpcnt == 0) {
            cout << 0;
            return;
        }
    }

    bt(0, 0);

    if(result == MAX) {
        cout << -1;
    }
    else cout << result-1;
}

void input() {
    cin >> N >> M;

    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++) {
            cin >> graph[i][j];

            if(graph[i][j] == 2) virus.push_back({i, j});		// 바이러스 위치 저장

            if(graph[i][j] != 1) {			// 벽이 아닌경우 카운트(격자가 모두 벽으로 이루어진경우 예외처리)
                tmpcnt++;
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    input();
    solve();
}

 

 

회고록

구현하는데 30~40분 정도 걸린것 같다 중간중간 코드 실수가 있었고 답이 안나오는 경우, 모든 격자가 벽으로만 이루어지는걸

생각을 못했다 조금더 빨리 구현할 수 있게 계획을 잘 세워야할 것 같다.

728x90
저작자표시 (새창열림)

'Algorithm' 카테고리의 다른 글

[백준] 13901번 로봇 (C++)  (0) 2025.08.09
[백준] 17124번 두 개의 배열 (C++)  (0) 2025.08.08
[백준] 2473번 세 용액 (C++)  (0) 2025.08.06
[백준] 12849번 본대 산책 (C++)  (0) 2025.08.05
[백준] 9024번 두 수의 합 (C++)  (0) 2025.08.04
'Algorithm' 카테고리의 다른 글
  • [백준] 13901번 로봇 (C++)
  • [백준] 17124번 두 개의 배열 (C++)
  • [백준] 2473번 세 용액 (C++)
  • [백준] 12849번 본대 산책 (C++)
쿨쿨.
쿨쿨.
  • 쿨쿨.
    All of the life
    쿨쿨.
  • 전체
    오늘
    어제
    • 분류 전체보기 (287) N
      • Programming (54) N
        • C, C++ (18)
        • Python (6)
        • Java (1)
        • HTML,CSS,JS (3)
        • SQL(DB) (13)
        • SpringBoot (10) N
        • Android (2)
        • CI,CD (1)
      • Algorithm (173)
        • Review (4)
      • Security (14)
        • WebHacking (3)
        • Websecurity (11)
      • OS (19)
        • Linux (12)
        • Mac os (2)
      • 머신러닝 (1)
      • CS(Computer Science) (12)
        • 컴퓨터 네트워크 (3)
        • 컴퓨터 구조 (1)
        • 인공지능 (8)
      • Docker (2)
      • Dev Book Review (3)
        • Clean Code (1)
        • Effective Java (0)
        • Real MySQL (2)
      • SWM (1)
      • Review (6)
      • AWS (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    깊이우선탐색
    다이나믹 프로그래밍
    정렬
    에라토스테네스의 체
    브루트포스
    c언어
    재귀
    이분탐색
    BFS
    우선순위큐
    Bandit
    DP
    코딩
    DFS
    linux
    비트마스킹
    그리디
    우선순위 큐
    WebSecurity
    시뮬레이션
    투포인터
    구현
    Leviathan
    다익스트라
    누적합
    백트래킹
    트리
    백준
    그래프 이론
    wargame
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.6
쿨쿨.
[백준] 17141번 연구소 2 (C++)
상단으로

티스토리툴바