포스트

[백준][17837] 새로운 게임 2

이 포스트는 백준 사이트의 새로운 게임 2 문제 풀이입니다.

문제

문제


해결 과정

이 문제는 3차원 배열을 사용하여 풀 수 있는 문제입니다.
한 턴이 실행되는 과정은 아래와 같습니다.

  1. 1번부터 K번까지의 플레이어가 본인의 방향에 맞춰 이동
  2. 이동한 칸의 색상에 따라 행동
  3. 모든 플레이어가 이동할 때 마다 4개 이상 겹쳐진 것이 없는지 확인

여러 칸 중 파란색 칸에 도착하였을 때의 구현이 복잡했습니다.
문제에서 네 방향의 순서를 정해뒀기 때문에 \(((curr \, direction) + 2) \div 4\) 의 연산이 불가능하고
방향을 바꿔 새로운 칸에 도착하면 그 칸의 규칙을 다시 한번 실행 하기 때문입니다.

코드 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <iostream>
#include <vector>

using namespace std;

int dir_row[4]{ 0, 0, -1, 1 };
int dir_col[4]{ 1, -1, 0, 0 };
struct POINT {
    int row, col, dir;
};

int N, K;
vector<vector<int>> board;
vector<vector<vector<int>>> player_position;
vector<POINT> players;

void input();
bool can_simulation();
void move_player(vector<int>& next_player);
bool check_game_clear_condition();


int main() {
    input();

    int loop_time = 1;
    while(can_simulation() && loop_time <= 1'000) {
        loop_time += 1;
    }

    cout << (loop_time > 1'000 ? -1 : loop_time);

    return 0;
}


void input() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin >> N >> K;
    board.assign(N, vector<int>(N, 0));
    for (int row = 0; row < N; ++row) {
        for (int col = 0; col < N; ++col) {
            cin >> board[row][col];
        }
    }

    players.assign(K, POINT{});
    player_position.assign(N, vector<vector<int>>(N, vector<int>{}));
    for (int i = 0; i < K; ++i) {
        int row, col, dir;
        cin >> row >> col >> dir;
        players[i] = POINT{ row - 1, col - 1, dir - 1 };
        player_position[row - 1][col - 1].push_back(i);
    }
}

bool can_simulation() {
    for (int number = 0; number < K; ++number) {
        vector<int>& curr_players = player_position[players[number].row][players[number].col];
        for (auto it = curr_players.begin(); it != curr_players.end(); ++it) {
            if (*it == number) {
                vector<int> next_players = vector<int>(it, curr_players.end());
                curr_players.erase(it, curr_players.end());
                move_player(next_players);

                POINT curr = players[next_players[0]];
                for(int player : next_players) {
                    player_position[curr.row][curr.col].push_back(player);
                }
                break;
            }
        }
        
        if(check_game_clear_condition()) return false;
    }

    if(check_game_clear_condition()) 
        return false;
    else 
        return true;
}

void move_player(vector<int>& next_player) {
    POINT& bottom_player = players[next_player.front()];

    int new_row = bottom_player.row + dir_row[bottom_player.dir];
    int new_col = bottom_player.col + dir_col[bottom_player.dir];

    if (new_row < 0 || new_row >= N || new_col < 0 || new_col >= N || 2 == board[new_row][new_col]) {
        if(bottom_player.dir == 0) bottom_player.dir = 1;
        else if(bottom_player.dir == 1) bottom_player.dir = 0;
        else if(bottom_player.dir == 2) bottom_player.dir = 3;
        else if(bottom_player.dir == 3) bottom_player.dir = 2;

        new_row = bottom_player.row + dir_row[bottom_player.dir];
        new_col = bottom_player.col + dir_col[bottom_player.dir];
        if(0 <= new_row && new_row < N && 0 <= new_col && new_col < N
            && (2 != board[new_row][new_col])) {
            
            bottom_player.row = new_row;
            bottom_player.col = new_col;

            if(1 == board[new_row][new_col]) {
                next_player = vector<int>(next_player.rbegin(), next_player.rend());
            }
        }
    }
    else if (0 == board[new_row][new_col]) {
        bottom_player.row = new_row;
        bottom_player.col = new_col;
    }
    else if (1 == board[new_row][new_col]) {
        bottom_player.row = new_row;
        bottom_player.col = new_col;
        next_player = vector<int>(next_player.rbegin(), next_player.rend());
    }

    for (int number : next_player) {
        players[number].row = bottom_player.row;
        players[number].col = bottom_player.col;
    }
}

bool check_game_clear_condition() {
    for (int number = 0; number < K; ++number) {
        vector<int>& curr_players = player_position[players[number].row][players[number].col];
        if(curr_players.size() >= 4) return true;
    }
    return false;
}


실행 결과

결과

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.