hotamul의 개발 이야기

[Algorithm][C++] SWEA 1953. [모의 SW 역량테스트] 탈주범 검거 본문

myt-algorithm-practice/Samsung SW Certi Adv

[Algorithm][C++] SWEA 1953. [모의 SW 역량테스트] 탈주범 검거

hotamul 2021. 11. 5. 22:08

url: https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5PpLlKAQ4DFAUq 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

풀이 핵심

1. BFS 문제

 

2. 큐에 push 할 때 조건 (터널이 연결되어 있음) 을 잘 구현해야 한다.

먼저 터널 종류에 따른 방향 정보가 담긴 dr[7 + 1][4], dc[7 + 1][4] 배열을 미리 만들어 준다.

이 때 행은 터널 구조물 타입을 의미한다.

따라서 맵을 탐색하며 map[r][c] 에 0이 아닌 수가 들어 있다면 터널이 연결되어 있는지를 확인한다.

터널이 연결되어 있는지를 확인하는 방법은 현재 방향의 반대 방향 정보가 탐색 중인 위치 (map[nr][nc]) 의 터널에 있는지를 파악해주면 된다. 

...
int rev_dr = -1 * dr[type][dir]; // 반대 방향 
int rev_dc = -1 * dc[type][dir]; // 반대 방향
int next_type = map[nr][nc]; // 탐색 중인 위치 터널 타입
bool flag = false;
for (int next_dir = 0; next_dir < 4; next_dir++) {
  if (rev_dr == dr[next_type][next_dir] && \
    rev_dc == dc[next_type][next_dir]) {
    flag = true;
	}
}
if (!flag) { // flag가 true로 변하지 않았다면 터널 연결 되지 않음
  continue;
}
...

 

코드

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <queue>
#define MAXN    50
#define MAXM    50
using namespace std;
 
int T, N, M, R, C, L;
int map[MAXN][MAXM];
int visit[MAXN][MAXM];
struct INFO {
    int r, c, t;
};
const int dr[7 + 1][4] = {
    {0,},
    {1,0,-1,0},
    {1,-1,0,0},
    {0,0,0,0},
    {-1,0,0,0},
    {1,0,0,0},
    {1,0,0,0},
    {-1,0,0,0}
};
const int dc[7 + 1][4] = {
    {0,},
    {0,1,0,-1},
    {0,0,0,0},
    {1,-1,0,0},
    {0,1,0,0},
    {0,1,0,0},
    {0,-1,0,0},
    {0,-1,0,0}
};
 
inline void _init() {
    for (int r = 0; r < N; r++) {
        for (int c = 0; c < M; c++) {
            visit[r][c] = 0;
        }
    }
}
 
int solve() {
	_init(); // visit 초기화
    queue<INFO> q;
    visit[R][C] = true;
    q.push({ R,C,1 });
    while (!q.empty()) {
        INFO cur = q.front();
        q.pop();
        if (cur.t == L) {
            break;
        }
        int type = map[cur.r][cur.c];
        for (int dir = 0; dir < 4; dir++) {
            int nr = cur.r + dr[type][dir];
            int nc = cur.c + dc[type][dir];
            if (nr < 0 || nr >= N || nc < 0 || nc >= M || visit[nr][nc]) {
                continue;
            }
            if (map[nr][nc]) {
                int rev_dr = -1 * dr[type][dir];
                int rev_dc = -1 * dc[type][dir];
                int next_type = map[nr][nc];
                bool flag = false;
                for (int next_dir = 0; next_dir < 4; next_dir++) {
                    if (rev_dr == dr[next_type][next_dir] && \
                        rev_dc == dc[next_type][next_dir]) {
                        flag = true;
                    }
                }
                if (!flag) {
                    continue;
                }
                visit[nr][nc] = cur.t + 1;
                q.push({ nr,nc,cur.t + 1 });
            }
        }
    }
 
    int ret = 0;
    for (int r = 0; r < N; r++) {
        for (int c = 0; c < M; c++) {
            if (visit[r][c]) {
                ret++;
            }
        }
    }
    return ret;
}
 
int main() {
    // freopen("sample_input.txt", "r", stdin);
    scanf("%d", &T);
    for (int tc = 1; tc <= T; tc++) {
        scanf("%d %d %d %d %d", &N, &M, &R, &C, &L);
        for (int r = 0; r < N; r++) {
            for (int c = 0; c < M; c++) {
                scanf("%d", &map[r][c]);
            }
        }
        int ret = solve();
        printf("#%d %d\n", tc, ret);
    }
    return 0;
}
Comments