アルゴリズム::白準::シミュレーション::3055::脱出


1.問題の分析


1.1. 問題の意図.

  • この問題のタイプは、シミュレーションおよび実装である.
  • の質問を読み、複雑な条件をまとめて実施します.
  • 1.2. 問題条件

  • 水はハリネズミより先に移動しなければならない.
  • 水は石と巣を通ることができません.
  • ハリネズミは石と水を通ることができません.
  • 最初は複数の水があったかも!!
  • 2.問題解決

  • の出発地と目的地を決定し、BFSを用いて最適化した.
  • 水も移動ハリネズミも移動するので2つのqueueを使います.
  • ハリネズミは予定の水満の格子を通ることができないので、水は先に移動します.
  • 分ごとに水中の元素を移動し、
    ハリネズミqueueの元素を移動し、
    目的地に到着した場合は、1分間繰り返し追加します.
  • Tip:意外にも、チェック範囲のコードが多すぎると、大きなオーバーヘッドが発生します.この場合、私は量詞にもう一つの格を加えて使います.これはもっと効率的で速いです

    3.コード

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    
    int d[4][2] = {{-1, 0}, {0, 1}, {0, -1}, {1, 0}};
    int R, C, goalY, goalX;
    bool visited[52][52];
    char map[52][52];
    queue<pair<int, int>> qWater, qMole;
    
    int simulate() {
    	int tick = 0;
    	while (!qMole.empty()) {
    		// 먼저 현재 phase에서 물이 있는 칸을 이동시킨다.
    		int numWater = qWater.size();
    		while (numWater--) {
    			int cy = qWater.front().first, cx = qWater.front().second;
    			qWater.pop();
    			for (int i = 0; i < 4; ++i) {
    				int ny = cy + d[i][0], nx = cx + d[i][1];
    				// 물은 돌과 목적지를 지나갈 수 없다.
    				if (map[ny][nx] == '.') {
    					map[ny][nx] = '*';
    					qWater.push({ny, nx});
    				}
    			}
    		}
    		// 그 뒤 현재 phase에서 고슴도치가 있을 수 있는 칸을 이동시킨다.
    		int numMole = qMole.size();
    		while (numMole--) {
    			int cy = qMole.front().first, cx = qMole.front().second;
    			qMole.pop();
    			visited[cy][cx] = true;
    			if (cy == goalY && cx == goalX) return tick;
    			
    			for (int i = 0; i < 4; ++i) {
    				int ny = cy + d[i][0], nx = cx + d[i][1];
    				// 고슴도치는 물과 돌을 지나갈 수 없다.
    				if (map[ny][nx] != 'X' && map[ny][nx] != '*'&& !visited[ny][nx]) {
    					visited[ny][nx] = true;
    					qMole.push({ny, nx});
    				}
    			}
    		}
            tick++;
    	}
    	return -1;
    }
    
    int main() {
    	ios::sync_with_stdio(false), cin.tie(NULL);
    	cin >> R >> C;
    	memset(map, 'X', sizeof(map));
    	
    	for (int y = 1; y <= R; ++y)
    		for (int x = 1; x <= C; ++x) {
    			cin >> map[y][x];
    			if (map[y][x] == 'D') goalY = y, goalX = x;
    			else if (map[y][x] == 'S') qMole.push({y, x});
    			else if (map[y][x] == '*') qWater.push({y, x});
    		}
    	int answer = simulate();
    	if (answer == -1) cout << "KAKTUS";
    	else cout << answer;
    }

    4.結果