본문 바로가기

백준/BFS

움직이는 미로탈출

728x90

www.acmicpc.net/problem/16954

 

16954번: 움직이는 미로 탈출

욱제는 학교 숙제로 크기가 8×8인 체스판에서 탈출하는 게임을 만들었다. 체스판의 모든 칸은 빈 칸 또는 벽 중 하나이다. 욱제의 캐릭터는 가장 왼쪽 아랫 칸에 있고, 이 캐릭터는 가장 오른쪽

www.acmicpc.net

#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<string>

using namespace std;


int n = 8; 
int m = 8;

int dx[] = { -1,1,0,0,1,1 ,-1,-1,0};
int dy[] = { 0,0,1,-1,-1,1,1,-1,0}; //comma 잘 좀 찍자...바보야

vector<vector<char>>arr(8, vector<char>(8));                //or vector
int check[9][9][100];
vector<pair<int, int>>wall;

typedef struct {

	int x;
	int y;
	int sec;

}info;

void move() {

	for (int i = 0; i < wall.size(); i++) {
		
		int x = wall[i].first;
		int y = wall[i].second;

		if (x + 1 <= 7) {
		
			wall[i].first = x + 1;  // 벽을 내려준다
		}
		else if (x + 1 >= 8) {
		//	arr[x][y] = '.';
			wall.erase(wall.begin()+i);  // 맨바닥에 있을 때는 벽을 없애준다
			i--; //없애준거 생각해서 for문에서 ++ 할테니까 i 그대로 유지시키기 위해 -- 해줌
		}
	}


}

void simulate() {
	vector<vector<char>>v(8,vector<char>(8,'.'));
	for (int i = 0; i < wall.size(); i++) {
		
		v[wall[i].first][wall[i].second] = '#';   // 벽의 위치 리스트를 보고 다시 arr을 그려준다.(벽이 move한 것을 반영시키기 위해)
	}
	arr = v;


}




int bfs(info p) {
	queue<info>q;
	q.push(p);
	int t = 1;
	while (!q.empty()) {


		int x = q.front().x;
		int y = q.front().y;
		int sec = q.front().sec;
		q.pop();
	

		//벽을 언제 움직이게 할지가 고민 이었음 -> sec가 t로 변할 때마다 (bfs level 이 달라질 때마다) 벽을 움직이게 했다. 
		if (sec == t) { 
			move();     //벽의 좌표를 내려주고
			simulate(); //직접 arr에 반영시킨다. 
			t++;
		}

		if (arr[x][y] == '#') { //좌표가 바뀐 후에 벽과 현재 위치와 겹치면 바로 끝나는 것
			continue;  }
		
		if (x == 0 && y == 7) { return 1; } //도착

		for (int i = 0; i < 9; i++) { 

			int nx = x + dx[i]; 
			int ny = y + dy[i];  

			if (nx >= 0 && nx < 8 && ny >= 0 && ny < 8) { // 대각선,위,아래,좌우,그대로 
				
				if (arr[nx][ny] == '.' && check[nx][ny][sec+1]==0) { // 벽인지를 검사한다,  해당 위치의 특정시간에 방문했는지를 따져준다.

					check[nx][ny][sec + 1] = 1; 
					q.push({ nx,ny,sec+1 });
					
				}
			}

		}
	}
	return 0;
}

int main() {
	
	memset(check, 0, sizeof(check));

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			
			cin >> arr[i][j];
			if (arr[i][j] == '#') {
				wall.push_back(make_pair(i, j));
			}
		
		}
	}

	cout << bfs({7,0,0}) << endl;


}

- bfs 레벨이 바뀔때 벽을 움직이고 시뮬레이션을 해야한다. 

- dx, dy 배열의 comma가 제대로 안찍혀서 잘 안돌아갔다 바보같은 실수였다.

'백준 > BFS' 카테고리의 다른 글

4연산  (0) 2021.03.16
아기 상어  (0) 2021.03.15
벽부수고 이동하기3  (0) 2021.03.08
벽부수고 이동하기2  (0) 2021.03.07
벽부수고이동하기4 - 플러드 필  (0) 2021.03.05