Baekjoon

Baekjoon 17780번 새로운 게임

ppwag 2020. 10. 19. 13:21

문제

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

걸린 시간

03 : 21 : 42

풀이

C++

#include <bits/stdc++.h>
#define INF 1e9
typedef long long ll;
typedef unsigned long long ull;
using namespace std;

int n, k, y, x, d;
int dy[4] = {0, 0, -1, 1}; // E, W, N, S
int dx[4] = {1, -1, 0, 0};
vector<pair<pair<int, int>, int>> piece; // location, direction
vector<vector<pair<int, vector<int>>>> board;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> k;
    board.resize(n, vector<pair<int, vector<int>>>(n));
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
            cin >> board[i][j].first;
    for(int i = 0; i < k; i++){
        cin >> y >> x >> d;
        piece.push_back(make_pair(make_pair(y-1, x-1), d-1));
        board[y-1][x-1].second.push_back(i);
    }
    int turn = 1;
    while(turn <= 1000){
        for(int i = 0; i < piece.size(); i++){
            // current y, x, direction
            int cy = piece[i].first.first;
            int cx = piece[i].first.second;
            int cd = piece[i].second;
            if(board[cy][cx].second[0] != i) continue;
            int ny = cy+dy[cd];
            int nx = cx+dx[cd];
            int nc; // next color
            if(0 <= ny && ny < n && 0 <= nx && nx < n)
                nc = board[ny][nx].first;
            else
                nc = 2;
            switch(nc){
                case 0: // white
                    if(board[ny][nx].second.size() + board[cy][cx].second.size() >= 4){
                        cout << turn;
                        return 0;
                    }
                    for(int i = 0; i < board[cy][cx].second.size(); i++){
                        piece[board[cy][cx].second[i]].first.first = ny;
                        piece[board[cy][cx].second[i]].first.second = nx;
                    }
                    board[ny][nx].second.insert(board[ny][nx].second.end(), board[cy][cx].second.begin(), board[cy][cx].second.end());
                    board[cy][cx].second.clear();
                    break;
                case 1: // red
                    if(board[ny][nx].second.size() + board[cy][cx].second.size() >= 4){
                        cout << turn;
                        return 0;
                    }
                    for(int i = 0; i < board[cy][cx].second.size(); i++){
                        piece[board[cy][cx].second[i]].first.first = ny;
                        piece[board[cy][cx].second[i]].first.second = nx;
                    }
                    reverse(board[cy][cx].second.begin(), board[cy][cx].second.end());
                    board[ny][nx].second.insert(board[ny][nx].second.end(), board[cy][cx].second.begin(), board[cy][cx].second.end());
                    board[cy][cx].second.clear();
                    break;
                case 2: // blue
                    int rd; // reverse direction
                    switch(cd){
                        case 0:
                            rd = 1;
                            break;
                        case 1:
                            rd = 0;
                            break;
                        case 2:
                            rd = 3;
                            break;
                        case 3:
                            rd = 2;
                            break;
                    }
                    piece[i].second = rd;
                    ny = cy+dy[rd];
                    nx = cx+dx[rd];
                    if(0 <= ny && ny < n && 0 <= nx && nx < n){
                        switch(board[ny][nx].first){
                            case 0:
                                if(board[ny][nx].second.size() + board[cy][cx].second.size() >= 4){
                                    cout << turn;
                                    return 0;
                                }
                                for(int i = 0; i < board[cy][cx].second.size(); i++){
                                    piece[board[cy][cx].second[i]].first.first = ny;
                                    piece[board[cy][cx].second[i]].first.second = nx;
                                }
                                board[ny][nx].second.insert(board[ny][nx].second.end(), board[cy][cx].second.begin(), board[cy][cx].second.end());
                                board[cy][cx].second.clear();
                                break;
                            case 1:
                                if(board[ny][nx].second.size() + board[cy][cx].second.size() >= 4){
                                    cout << turn;
                                    return 0;
                                }
                                for(int i = 0; i < board[cy][cx].second.size(); i++){
                                    piece[board[cy][cx].second[i]].first.first = ny;
                                    piece[board[cy][cx].second[i]].first.second = nx;
                                }
                                reverse(board[cy][cx].second.begin(), board[cy][cx].second.end());
                                board[ny][nx].second.insert(board[ny][nx].second.end(), board[cy][cx].second.begin(), board[cy][cx].second.end());
                                board[cy][cx].second.clear();
                                break;
                            case 2:
                                // do nothing
                                break;
                        }
                    }
                    break;
            }
        }
        turn++;
    }
    cout << -1;
    return 0;
}
  1. '상' 방향값 잘못 설정.
  2. 모든 말의 개수만큼 반복하지 않음.
  3. "가장 아래에 있는 말만 이동할 수 있다." 말만 -> 말로만 으로 이해.
  4. 말들이 같이 이동할 때 쌓여져 있는 다른 말들의 좌표를 수정해주지 않음.

문제 이해부터 구현까지 모두 꼼꼼하지 못해서 디버깅에 아주 많은 시간이 걸렸다. 구현, 시뮬레이션 문제에서는 되도록이면 구조체나 클래스를 따로 작성해서 구현하는 편이 좋을 것 같다.

'Baekjoon' 카테고리의 다른 글

Baekjoon 1800번 인터넷 설치  (0) 2020.10.21
Baekjoon 16918번 봄버맨  (0) 2020.10.19
Baekjoon 15591번 MooTube (Silver)  (0) 2020.10.19
Baekjoon 10021번 Watering the Fields  (0) 2020.10.15
Baekjoon 11967번 불켜기  (0) 2020.10.14

댓글