13460 구슬 탈출 2 > 2024KB, 28ms

BFS로 풀어볼 것

 

내가 푼 방법 : 

  • 기본적으로 DFS로 풀었음
  • 상하좌우 DFS 반복해주되 만약 그 방향으로 했을 때 공이 움직이지 않았다면 그 방향은 제외해주고 DFS (while_cnt)
  • 공만 움직이고 map은 그대로이기 때문에 map은 그대로 놔두고 빨간공과 파란공의 위치만 저장하고 복사함
    • 처음에는 map 모두 복사했다가 시간초과
  • 간단한 로직
    • 상하좌우 DFS 들어감
    • 빨간 공 움직이고 파란 공 움직임
    • 각 움직임은 함수로 구현했는데 0 : 안움직 안들어감, 1 : 움직 안들어감, 2 : 움직 들어감을 뜻함
    • 만약 둘 다 안움직였으면 한 차례가 끝난 것이고 파란색이 들어갔으면 종료, 빨간색이 들어갔으면 빨간색은 이제 안 움직인다고 생각하고 파란색을 움직임. 여기서 파란색이 들어가면 종료, 파란색이 안들어가면 움직인 최솟값이랑 비교해서 갱신 시켜줌

 

=> 다른 사람들에 비해 느리고 메모리 많이 먹음.

 

#include <iostream>
#include <string>

#define MAX 10
using namespace std;

typedef struct r {
    int y, x;
}R;

typedef struct b {
    int y, x;
}B;

int result = 100;
int N, M;
string map[MAX];
R ori_r;
B ori_b;

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

void input() {
    cin >> N >> M;

    for (int i = 0; i < N; i++)
        cin >> map[i];
   
    for (int i = 0; i < N; i++)
        for (int j = 0; j < M; j++) {
            if (map[i][j] == 'R') {
                ori_r.y = i; ori_r.x = j;
                map[i][j] = '.';
            }
            if (map[i][j] == 'B') {
                ori_b.y = i; ori_b.x = j;
                map[i][j] = '.';
            }
        }
}

int red_move(int dir, R& r_ori, B& b_ori) {
    int new_y, new_x;
    int b_y = b_ori.y, b_x = b_ori.x, r_y = r_ori.y, r_x = r_ori.x;
    new_y = r_y + dy[dir]; new_x = r_x + dx[dir];
    while (map[new_y][new_x] == '.' && !(new_y == b_y && new_x == b_x)) { 
        new_y += dy[dir]; new_x += dx[dir]; 
    }

    switch (map[new_y][new_x]) {
    case 'O':
        r_ori.y = -1, r_ori.x = -1;
        return 2;
    case '#':
        if (new_y - dy[dir] == r_y && new_x - dx[dir] == r_x)
            return 0;
        else {
            r_ori = { new_y - dy[dir], new_x - dx[dir] };
            return 1;
        }
    case '.':
        if (new_y - dy[dir] == r_y && new_x - dx[dir] == r_x)
            return 0;
        else {
            r_ori = { new_y - dy[dir], new_x - dx[dir] };
            return 1;
        }
    }
}

int blue_move(int dir, R &r_ori, B &b_ori) {
    int new_y, new_x;
    int b_y = b_ori.y, b_x = b_ori.x, r_y = r_ori.y, r_x = r_ori.x;
    new_y = b_y + dy[dir]; new_x = b_x + dx[dir];
    while (map[new_y][new_x] == '.' && !(new_y == r_y && new_x == r_x)) {
        new_y += dy[dir]; new_x += dx[dir];
    }

    switch (map[new_y][new_x]) {
    case 'O':
        b_ori.y = -1, b_ori.x = -1;
        return 2;
    case '#':
        if (new_y - dy[dir] == b_y && new_x - dx[dir] == b_x)
            return 0;
        else {
            b_ori = { new_y - dy[dir], new_x - dx[dir] };
            return 1;
        }
    case '.':
        if (new_y - dy[dir] == b_y && new_x - dx[dir] == b_x)
            return 0;
        else {
            b_ori = { new_y - dy[dir], new_x - dx[dir] };
            return 1;
        }
    }
}

void DFS(int dir, int cnt, R r_ori, B b_ori) {
    if (cnt == 11) return;

    R r_copy = { r_ori.y, r_ori.x };
    B b_copy = { b_ori.y, b_ori.x };

    int red_result = red_move(dir, r_copy, b_copy);
    int blue_result = blue_move(dir, r_copy, b_copy);
    bool red_flag = false;
    int while_cnt = 0;
    // 0 : 안움직 안들어감, 1 : 움직 안들어감, 2 : 움직 들어감
    while (1) {
        if (red_result == 0 && blue_result == 0) break;

        if (blue_result == 2) return;
        if (red_result == 2) red_flag = true;

        if (red_flag) red_result = 0;
        else red_result = red_move(dir, r_copy, b_copy);

        blue_result = blue_move(dir, r_copy, b_copy);
        
        while_cnt++;
    }

    if (red_flag) {
        if (result > cnt) {
            result = cnt;
        }
        return;
    }
        

    for (int i = 0; i < 4; i++) {
        if (while_cnt == 0 && i == dir) continue;
        DFS(i, cnt + 1, r_copy, b_copy);
    }
        
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    input();

    for (int i = 0; i < 4; i++)
        DFS(i, 1, ori_r, ori_b);
    
    if (result == 100) cout << -1;
    else cout << result;
}

'coding > baekjoon_codingstudy' 카테고리의 다른 글

21609 상어중학교  (0) 2022.10.02
19238 스타트택시  (0) 2022.10.02
14891 톱니바퀴 (골드 5)  (0) 2021.10.05
18239 편안한 수열 만들기 (골드 3)  (0) 2021.08.19
11657 타임머신 (골드 4)  (0) 2021.08.15

+ Recent posts