ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 2665(미로만들기)
    전공/알고리즘 2020. 6. 28. 16:40

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

     

    2665번: 미로만들기

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

    www.acmicpc.net

    N^2의 격자에 흰색과 검은색이 존재한다. 검은색은 벽으로 이루어져서 지나갈 수 없다.

     

    하지만 벽을 부술 수 있다. 최소 몇번의 벽을 부셔야 시작점에서 종료지점까지 갈 수 있는가

     

    어디 지점에서 어디 까지 가는 방법 => dfs, bfs 

     

     

    사실 먼저 dfs를 생각했다. dfs의 재귀함수로 몇 번의 벽을 부술지 기록하기가 더 쉽다고 생각했지만, 역시 문제점은 시간 만약에 dfs로 구현하게 된다면 벽이 보이는대로 다 부술테고 최소의 벽 부수기를 원하는 문제에는 알맞지 않다고 생각을 하였다. 

     

    따라서 bfs와 priority_queue를 이용해서 벽을 더 적게 부순 경우를 먼저 조사하였다. 

     

    bfs의 작동방법을 서술하면 

    일단 네 방향으로 퍼진다. 

    네 방향 중에 이동할 수 없는 경우인 경우 skip(index범위 초과, 이미 방문한 곳(벽 부순 횟수까지))

    그 퍼진 곳 중에 벽이면 벽을 뚫고 priority_queue에 넣는다. 값에 벽 뚫은 횟수 +1

    벽이 아닌 경우에 그대로 priority_queue에 넣는다.

    queue가 빌때까지 반복

     

    그리고 만약에 도착점에 도달했으면 벽 뚫은 횟수가 무조건 최솟값이므로 그 값을 출력.

     

    #include<iostream>
    #include<queue>
    #include<utility>
    using namespace std;
    #define MAX 50
    
    priority_queue<pair<int , pair<int, int> > > pq;
    pair<int, pair<int,int> > p;
    int N, answer;
    int room[MAX][MAX];
    int dx[4] = { 1,-1,0,0 };
    int dy[4] = { 0,0,1,-1 };
    bool visited[MAX][MAX][MAX] = { false };
    
    void bfs() {
    	while (!pq.empty()) {
    		p = pq.top();
    		pq.pop();
    		if (p.second.first == N - 1 && p.second.second == N - 1) {
    			answer = -p.first;
    			return;
    		}
    		for (int i = 0; i < 4; i++) {
    			int x = p.second.first + dx[i];
    			int y = p.second.second + dy[i];
    			if (x < 0 || y < 0 || x >= N || y >= N) continue;
    			if (visited[-p.first][x][y]) continue;
    			if (room[x][y] == 0) {
    				pq.push(make_pair(p.first - 1, make_pair(x, y)));
    				visited[-p.first + 1][x][y] = true;
    			}
    			else {
    				pq.push(make_pair(p.first, make_pair(x, y)));
    				visited[-p.first][x][y] = true;
    			}
    		}
    	}
    }
    
    int main() {
    	cin >> N;
    	for (int i = 0; i < N; i++) {
    		for (int j = 0; j < N; j++) {
    			char a;
    			cin >> a;
    			room[i][j] = a - '0';
    		}
    	}
    
    	pq.push(make_pair(0, make_pair(0, 0)));
    	bfs();
    	cout << answer << "\n";
    }

     

    '전공 > 알고리즘' 카테고리의 다른 글

    백준 1916(최소비용 구하기)  (0) 2020.06.29
    백준 1753(최단경로)  (0) 2020.06.29
    백준 1719(택배)  (0) 2020.06.28
    백준 1504(특정한 최단 경로)  (0) 2020.06.26
    백준 1238(파티)  (0) 2020.06.26

    댓글

Designed by Tistory.