[伯俊]206壁を破って移動


白準2206壁を破壊して移動

  • https://www.acmicpc.net/problem/2206

  • 最小セルを通過するパスをマッピングで検索
    ->すべてのウェイトが同じ場合の最短距離を求める
    ->幅優先ナビゲーション(BFS)
  • #include <iostream>
    #include <string>
    #include <queue>
    #include <utility>
    #include <algorithm>
    using namespace std;
    
    const int MAXN = 1000;
    const int IMPOSSIBLE = 2000000;
    
    int N, M;
    string mp[MAXN + 2];
    bool isVisited[MAXN + 2][MAXN + 2][2] = { 0 };
    queue<pair<pair<int, int>, pair<int,int>>> que;
    //pair<pair<r좌표, c좌표>, pair<state, dist> 저장
    //state 0: 벽 부술 수 없음
    //state 1: 벽 하나 부술 수 있음
    int dirR[4] = {-1,0,0,1};
    int dirC[4] = {0,-1,1,0};
    
    
    int bfs() {
    	//시작 좌표 
    	que.push(make_pair(make_pair(1, 1), make_pair(1, 1)));
    
    	int minDist = IMPOSSIBLE;
    	while (!que.empty()) {
    		pair<pair<int, int>, pair<int, int>> cur = que.front();
    		que.pop();
    
    		int curR = cur.first.first;
    		int curC = cur.first.second;
    		int curState = cur.second.first;
    		int curDist = cur.second.second;
    
    		//이미 방문한 선택지면 건너뛰기
    		if (isVisited[curR][curC][curState]) 
    			continue; 
    		//방문 체크
    		isVisited[curR][curC][curState] = true;
    
    		//도착 좌표인 경우 minDist 갱신
    		if (curR == N && curC == M) {
    			minDist = min(minDist, curDist);
    			continue;
    		}
    		
    		//현재 좌표 벽 유무 확인
    		if (mp[curR][curC] == '1') {
    			//벽 부수기
    			if (curState == 1) curState = 0;
    			//벽을 부술 수 없는 상태인 경우 더이상 이동할 수 없다
    			else continue;
    		}
    
    		//다음 좌표로 이동
    		for (int i = 0; i < 4; i++) {
    			int nextR = curR + dirR[i];
    			int nextC = curC + dirC[i];
    
    			if (nextR < 1 || nextR > N) continue;
    			if (nextC < 1 || nextC > M) continue;
    
    			que.push(make_pair(make_pair(nextR, nextC), make_pair(curState, curDist + 1)));
    		}
    	}
    
    	if (minDist == IMPOSSIBLE) return -1;
    	return minDist;
    }
    
    int main() {
    	ios_base::sync_with_stdio(false);
    	cin.tie(NULL);
    	cout.tie(NULL);
    
    	cin >> N >> M;
    	for (int i = 1; i <= N; i++) {
    		string input;
    		cin >> input;
    		//string의 인덱스를 1부터 검사할 수 있도록
    		//input의 맨 앞에 의미없는 문자 하나를 붙임
    		mp[i] = "0" + input;
    	}
    	
    	cout << bfs();
    	return 0;
    }