문제

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

걸린 시간

- 실패

풀이

C++

#include <bits/stdc++.h>
#define INF 1e9
typedef long long ll;
typedef unsigned long long ull;
using namespace std;

struct node{
    int y, x, move, key;
    node(int y, int x, int move, int key){
        this->y = y;
        this->x = x;
        this->move = move;
        this->key = key;
    }
};

int n, m;
int dy[4] = {1, -1, 0, 0};
int dx[4] = {0, 0, -1, 1};
map<tuple<int, int, int>, int> visited;
vector<vector<char>> maze;
queue<node> q;

int bfs(){
    while(!q.empty()){
        int y = q.front().y;
        int x = q.front().x;
        int move = q.front().move;
        int key = q.front().key;
        q.pop();
        if(maze[y][x] == '1') return move;
        for(int j = 0; j < 4; j++){
            int ny = y+dy[j];
            int nx = x+dx[j];
            if(0 <= ny && ny < n && 0 <= nx && nx < m && !visited[make_tuple(key, ny, nx)]){
                int nextKey = key;
                int ascii = (int)maze[ny][nx];
                if(0x61 <= ascii && ascii <= 0x7a){
                    nextKey |= (1<<(ascii-0x61));
                    visited[make_tuple(nextKey, ny, nx)] = 1;
                    q.push(node(ny, nx, move+1, nextKey));
                }
                else if(0x41 <= ascii && ascii <= 0x5a){
                    if(key&(1<<(ascii-0x41))){
                        visited[make_tuple(key, ny, nx)] = 1;
                        q.push(node(ny, nx, move+1, key));
                    }
                }
                else if(maze[ny][nx] != '#'){
                    visited[make_tuple(key, ny, nx)] = 1;
                    q.push(node(ny, nx, move+1, key));
                }
            }
        }
    }
    return -1;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> m;
    maze.resize(n, vector<char>(m));
    for(int y = 0; y < n; y++){
        for(int x = 0; x < m; x++){
            cin >> maze[y][x];
            if(maze[y][x] == '0'){
                q.push(node(y, x, 0, 0));
                visited[make_tuple(0, y, x)] = 1;
            }
        }
    }
    cout << bfs();
    return 0;
}

며칠 전 백조의 호수 문제를 풀었던 기억을 되살려 호수의 얼음이 조금씩 녹듯이, 열쇠를 찾을 때 마다 이동할 수 있는 미로의 범위를 늘려 나가는 식으로 풀이하려 했지만 반례가 너무나 많았다. 현재까지 발견한 열쇠를 비트마스킹 기법을 적용해 정수형태로 관리하고 bfs 를 보유중인 열쇠방문한 좌표를 상태로 하는 방문 배열을 사용하여 진행시키면 된다.

'Baekjoon' 카테고리의 다른 글

Baekjoon 17825번 주사위 윷놀이  (0) 2020.11.03
Baekjoon 3108번 로고  (0) 2020.11.02
Baekjoon 14442번 벽 부수고 이동하기 2  (0) 2020.11.01
Baekjoon 6087번 레이저 통신  (0) 2020.10.31
Baekjoon 2151번 거울 설치  (0) 2020.10.30

댓글