알고리즘/백준

백준 2665 미로만들기 c++ [컴공과고씨]

시간빌게이츠 2022. 8. 12. 15:36
반응형

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

 

2665번: 미로만들기

첫 줄에는 한 줄에 들어가는 방의 수 n(1 ≤ n ≤ 50)이 주어지고, 다음 n개의 줄의 각 줄마다 0과 1이 이루어진 길이가 n인 수열이 주어진다. 0은 검은 방, 1은 흰 방을 나타낸다.

www.acmicpc.net

 

문제 정리

바둑판 모양이 있음.

각 방 마다 지나갈 수 있는 방과 없는 방으로 나뉨.

갈수 없는 방은 뚫 수 있음. 

(0,0) 에서 (n-1,n-1)까지 가는데 방을 최소한으로 뚫어서 갈 때 몇 개를 뚫어야 하는가?

 

문제 해결 방법

BFS를 사용해서 탐색을 하는데 각 방 마다 뚫고 온 방의 개수를 적어서 BFS 탐색을 해주면 됩니다.

방의 초기 값은 크게 잡아 줍니다. 그 후 시작점은 0으로 해줍니다.

BFS를 시작하면 각 방으로 들어갑니다. 

이 때 다음 방이 막힌 방이라면 이제 까지 뚫고 온 개수에 1을 더하고 저장된 개수와 비교하여 저장된 개수 보다 적을 때만 저장해 줍니다.

다음 방이 빈 방이라면 이제 까지 뚫고 온 개수와 저장된 개수를 비교하여 저장된 개수 보다 뚫고 온 개수가 더 적을 때만 저장해주고 다음 방으로 넘어가도록 합니다.

 

왜냐하면 저장된 개수보다 뚫은 개수가 더 크다면 이미 정답이 될 수 없으므로 더 이상 탐색할 필요가 없습니다. 또한 같은 경우는 중복 탐색이므로 마찬가지로 더 이상 탐색 할 필요가 없습니다.

 

전체 코드

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
#include <iostream>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
int n;
int map[52][52]; // 빈 방, 막힌 방
int visit[52][52]; // 뚫고 온 개수 저장
int dx[] = {00-11}; // 상하좌우
int dy[] = {1-100}; // 상하좌우
 
void bfs(){
    queue<pair<intint>> q;
    q.push(make_pair(00));
    visit[0][0= 0// 시작 점은 0으로 세팅
    while(!q.empty()){
        int x = q.front().first; 
        int y = q.front().second;
        q.pop();
        
        for (int i = 0; i < 4; i++){
            int nx = x + dx[i]; // 다음 x 좌표
            int ny = y + dy[i]; // 다음 y 좌표
            if(nx >=0 && nx < n && ny>=0 && ny <n){
                if(map[ny][nx] == 1){ // 갈 수 있는 방
                    if(visit[ny][nx] > visit[y][x]){
                        //뚫고 온 방의 개수 비교 
                        visit[ny][nx] = visit[y][x];
                        q.push(make_pair(nx, ny)); // 다음 방으로 이동
                    } 
                }else// 비어 있는 방
                    if(visit[ny][nx] > visit[y][x]+1){
                        //뚫고 온 방의 개수 비교
                        visit[ny][nx] = visit[y][x]+1;
                        q.push(make_pair(nx, ny)); // 다음 방으로 이동
                    } 
                }
            }
        }  
    }     
}
 
int main(){
    ios::sync_with_stdio(false);
    cin >> n;
    char a;
    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            cin >> a;
            map[i][j] = a - '0'// 입력을 int로 바꾸어줌
        }
    }
    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            visit[i][j] = 987654321// 최대 값
        }
    }
    bfs();
    cout << visit[n - 1][n - 1<< endl;
 
    return 0;
}
cs

 

체감 난이도 걸린 시간 후기 사용 알고리즘
1H 간단한 문제 였는데 처음에 백트래킹으로 풀어
시간초과로 푸는데 오래 걸렸음.
BFS
반응형