ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준 2178] 미로 탐색
    C 프로그래밍/BOJ 2022. 9. 5. 19:45
    728x90

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

     

    2178번: 미로 탐색

    첫째 줄에 두 정수 N, M(2 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 M개의 정수로 미로가 주어진다. 각각의 수들은 붙어서 입력으로 주어진다.

    www.acmicpc.net

    #include <cstdio>
    #include <iostream>
    #include <queue>
    int N, M;	// 행, 열
    char board[100 + 10][100 + 10];
    bool visited[100 + 100][100 + 100];
    
    struct _st
    {
    	int a;
    	int b;
    	int t;
    };
    
    std::queue<_st> Q;
    
    void input(void)
    {
    	scanf("%d %d", &N, &M);
    	for (int i = 1; i <= N; i++) {
    		scanf("%s", &board[i][1]);	// (1, 1)부터 시작
    	}
    }
    
    int maze(void)
    {
    	int dir_x[4] = { 0, 0, 1, -1 };
    	int dir_y[4] = { 1, -1, 0, 0 };
    
    	Q.push({ 1, 1, 1 });	// (1, 1) 칸도 카운팅
    	visited[1][1] = true;
    
    	while (!Q.empty()) {
    		_st data = Q.front();
    		Q.pop();
    
    		for (int p = 0; p < 4; p++) {
    			int na = data.a + dir_x[p];
    			int nb = data.b + dir_y[p];
    			int ntime = data.t + 1;
    
    			if (na == N && nb == M) return ntime;
    
    			if (na < 1 || na > N || nb < 1 || nb > M || visited[na][nb] == true || board[na][nb] == '0') continue;
    			Q.push({ na, nb, ntime });
    			visited[na][nb] = true;
    		}
    	}
    }
    
    
    int main()
    {
    	input();
    	int ans = maze();
    	printf("%d", ans);
    	return 0;
    }

     

    이 문제는 전형적인 BFS 문제이다. 

    (1, 1)에서 (N, M)까지 가는 "최소 칸 수"를 묻고 있기 때문이다. 

    Queue 자료구조를 사용한 이유는 상태를 저장하기 위함이다. 먼저 저장시킨 상태를 먼저 꺼내어 사용함으로써 동일한 뎁스의 좌표를 먼저 탐색하도록 구현하였다. 

     

    // input( ) 함수

    (1, 1)가 시작점이므로 board 행과 열의 두번째 인덱스부터 시작해주기 위해 루프를 1부터 돌렸고, board[i][1] 부터 받았다. 이때 정수"%d"로 받을 수 없는 이유는 각각의 숫자가 붙어서 입력되기 때문이다(공백으로 구분되어 입력받을 때만 가능). 그래서 문자열"%s"로 받아주어야 한다. 

     

     

    // maze( ) 함수

    초기 세팅은 다음과 같다. 

    현재 위치에서 "한 칸" 단위로 갈 수 있는 위치를 탐색하기 위해 방향벡터(dir_x, dir_y)를 두었다.

    탐색의 시작인 (1, 1)위치를 큐에 넣고, 방문 배열인 visited의 (1, 1)위치를 true로 바꾸어 표시한다. 전역변수로 bool 배열을 만들면 디폴트는 false이기 때문이다. 

     

    그리고 큐에 원소가 없을 때 까지 반복문을 돌리면서 다음과 같은 과정을 수행한다. 

    구조체 data에 큐에 가장 상단에 있는(지금 당장 탐색할) 데이터를 저장한다. 그리고 해당 원소를 큐에서 꺼내준다. 

    다음으로 4 방향을 돌면서 새로운 좌표 (na, nb)가 (N, M)이면 걸린시간(ntime)을 리턴한다. 만약 좌표를 전진하면서 영역을 벗어나거나, 이미 방문한 좌표이거나, 벽을 만나면 큐에 원소를 푸시하지 않고 지나간다. 둘 다 아니라면 큐에 새로운 좌표를 추시하고, 방문배열을 true로 바꾸어 방문을 표시한다. 

    728x90

    'C 프로그래밍 > BOJ' 카테고리의 다른 글

    [백준 1963] 소수 경로  (0) 2022.09.05
    [백준 7562] 나이트의 이동  (0) 2022.09.05
    [백준 3190] 뱀  (0) 2022.09.04
    [백준 10655] 마라톤1  (0) 2022.09.02
    [백준 2428] 표절  (0) 2022.09.02

    댓글

Designed by Tistory.