컴퓨터기본/문제풀이

[정올] 2893 : 제리의 치즈먹기 (Cheese)

차가운오미자 2021. 10. 9. 11:59

http://jungol.co.kr/bbs/board.php?bo_table=pbank&wr_id=2156&sca=9030 

 

JUNGOL

 

www.jungol.co.kr

 

문제 이해 

제리의 체력이 치즈를 먹을 때마다 1씩 증가하고, 치즈는 1에서 N까지 하나씩만 있으므로, 

1에서 N까지의 치즈를 순서대로 하나하나씩 찾아가는 경로를 찾으면 된다.

최단 시간(경로) 를 찾으라고 했으니 BFS를 사용하는 문제일 것이다. 

 

좀 더 자세히 보자면

시작위치에서 1까지 가는 최단 경로를 BFS를 이용해서 찾고,

2에서 3까지의 최단 경로를 BFS를 이용해서 찾고 이런 식이다.

 

각 BFS를 호출할 때마다 큐와 visited 배열을 초기화 하는 것을 잊지 말자!!

 

추가적으로 주의해야할 점은, map을 문자열로 받기 때문에 정수와의 호환이 필요하다는 점이다.

다행히 치즈가 최대 9개라서, 각 치즈의 위치를 map 배열을 탐색해서 찾는 것도, BFS를 9번 호출하는 것도 가능하다.

 

작성 코드

#include <stdio.h>
#define SIZEY 1000
#define SIZEX 1000

int H, W, N;
char map[SIZEY + 10][SIZEX + 10];
int visited[SIZEY + 10][SIZEX + 10];

// 치즈 공장 좌표 
int desty[10];
int destx[10];

int ans;

typedef struct pos {
    int y;
    int x;
    int t;
}POS;

POS q[SIZEY * SIZEX + 10];
int wp, rp;

void enq(int y, int x, int t) {
    q[wp].y = y;
    q[wp].x = x;
    q[wp].t = t;
    wp++;
}

POS deq(void) {
    POS tmp = q[rp];
    rp++;
    return tmp;
}

int empty(void) {
    return wp == rp;
}

int dy[] = { -1, 1, 0, 0 };
int dx[] = { 0, 0, -1, 1 };

int BFS(int sy, int sx, int oy, int ox) {
    enq(sy, sx, 1);
    visited[sy][sx] = 1;

    while (!empty()) {
        POS cur = deq();

        if (cur.y == oy && cur.x == ox) return cur.t;

        for (int i = 0; i < 4; i++) {
            int ny = dy[i] + cur.y;
            int nx = dx[i] + cur.x;

            if (ny < 0 || ny >= H) continue;
            if (nx < 0 || nx >= W) continue;
            if (visited[ny][nx] > 0) continue;
            if (map[ny][nx] == 'X') continue;

            if (ny == oy && nx == ox) return cur.t + 1;
            visited[ny][nx] = cur.t;
            enq(ny, nx, cur.t + 1);
        }
    }
    return -1;
}

void Solve(void) {
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            if (map[i][j] >= '1' && map[i][j] <= '9') {
            // 1번부터 9번까지 치즈 위치 찾기
                desty[map[i][j] - '0'] = i;
                destx[map[i][j] - '0'] = j;
            }
            if (map[i][j] == 'S') {
            // 시작은 제리의 위치부터
                desty[0] = i;
                destx[0] = j;
            }
        }
    }

    for (int i = 0; i < N; i++) {
        // dest 배열의 i 번째 위치에서 i+1 번째 위치로 가는 BFS 수행
        ans += BFS(desty[i], destx[i], desty[i + 1], destx[i + 1])-1;
        
        // 초기화
        wp = 0, rp = 0;
        for (int i = 0; i < H; i++) {
            for (int j = 0; j < W; j++) {
                visited[i][j] = 0; // 초기화
            }
        }
    }
}

int main(void) {

    // get input
    scanf("%d %d %d", &H, &W, &N);
    for (int i = 0; i < H; i++) {
        scanf("%s", &map[i]);
    }
    Solve();
    printf("%d", ans);
    return 0;
}

 

'컴퓨터기본 > 문제풀이' 카테고리의 다른 글

[SWEA] 4014. 활주로 건설  (0) 2021.10.09
[SWEA] 4013. 특이한 자석  (0) 2021.10.09
[SWEA] 2383. 점심 식사시간  (0) 2021.10.09
[백준] 2477번: 참외밭  (2) 2021.09.26
[백준] 2667번: 단지번호붙이기  (0) 2021.09.26