본문 바로가기

c++/Baekjoon Online

백준 2206 : 벽 부수고 이동하기 C++

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

 

2206번: 벽 부수고 이동하기

N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로��

www.acmicpc.net

후기겸 풀이

 

1. 처음에 입력받을때 map[i][j]가 1인 좌표들을 wall 이라는 vector로 만들고, 순서대로 하나씩 벽 없애고 BFS 돌리니까 바로 시간초과 뜨더라....ㅎ

 

2. 그래서 구글링으로 벽 부순상태인지 아닌지 확인용 flag 추가하는 풀이 확인!

 -> visited도 벽을 부순 상태랑 안부순 상태 구분!

 -> int visit[1000][1000][2]; // 0이면 부순 상태 1이면 안부순 상태

1) 벽을 안부순 상태

 벽을 만나면 : 벽 부수고 flag =1로 만들고 이어서

 벽 아니면 : 그냥 BFS

 

2) 벽을 부순상태 (flag =1)

 벽만나면 : 그냥 패쓰

 벽 아니면: BFS

 

 

3. 아니 다 풀었는데 100%에서 틀렸습니다 떠서 혼자 해맸다

 입력이

1 1

0 일때 예외처리 해야되더라 

 

if (m == 1 && n == 1)
answer = 1;

-> 추가!

#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <queue>
#include <string>
using namespace std;

struct wall {
	int r, c, flag;
};

int map[1000][1000];
int visit[1000][1000][2]; // 마지막 1이면 벽 부순거 0이면 아직 벽 안부순 상태

int d_r[4] = { 0,0,1,-1 };
int d_c[4] = { 1,-1,0,0 };

int n,m;
int answer = 987654321;

void bfs() //0,0 에서 n,m까지!
{
	queue<wall> q;
	q.push({ 0,0,0 });
	visit[0][0][0] = 1;

	int result = 2;
	while (!q.empty())
	{
		int s = q.size();
		for (int h = 0; h < s; h++)
		{
			int flag = q.front().flag;// 1이면 벽 한번 부순상태, 0 이면 아직 한번도 안부순 상태
			int r = q.front().r;
			int c = q.front().c;
			q.pop();
			for (int i = 0; i < 4; i++)
			{
				int flag2 = flag;
				int new_r = r + d_r[i];
				int new_c = c + d_c[i];

				if (new_r == n - 1 && new_c == m - 1)//도착지
				{
					answer = result;
					return;
				}

				if (new_r < 0 || new_c < 0 || new_r >= n || new_c >= m)//지도밖
					continue;
				if (flag2 == 1)//벽 한번 부순 상태
				{
					if (map[new_r][new_c] == 1)//벽만났으면
						continue;
					if (visit[new_r][new_c][1])//이미 방문한 곳이면
						continue;

					visit[new_r][new_c][1] = 1;
				}
				else
				{
					if (visit[new_r][new_c][0])//이미 방문한 곳이면
						continue;

					if (map[new_r][new_c]==1)
					{ //벽이면 부수고, 벽 부순 경우 방문 맵에 체크 
						flag2 = 1;
						visit[new_r][new_c][1] = 1;
					}
					else
						visit[new_r][new_c][0] = 1;
				}

				q.push({ new_r,new_c,flag2 });
			}
		}

		result++;

	}

}

int main()
{
	string a;
	cin >> n >> m;
	for (int i = 0; i < n; i++)
	{
		cin >> a;
		for (int j = 0; j < m; j++)
		{
			map[i][j] = a[j] - '0';
		}
	}

	bfs();

	if (answer == 987654321)
		answer = -1;

	if (m == 1 && n == 1)
		answer = 1;

	cout << answer << endl;
	return 0;
}

 

'c++ > Baekjoon Online' 카테고리의 다른 글

백준 11559 : Puyo Puyo c++  (0) 2020.10.10
백준 17244 : 아맞다우산 c++  (0) 2020.10.08
백준 2146 : 다리만들기 C++  (0) 2020.10.07
백준 1254 : 팰린드롬 만들기  (0) 2020.10.03
백준 17135 : 캐슬 디펜스 C++  (0) 2020.09.28