본문 바로가기
Algorithm 💫/Problem Solving

[백준 17837번 새로운 게임/ C++]

by 돼지고기맛있다 2020. 12. 2.
반응형

www.acmicpc.net/problem/17837

 

17837번: 새로운 게임 2

재현이는 주변을 살펴보던 중 체스판과 말을 이용해서 새로운 게임을 만들기로 했다. 새로운 게임은 크기가 N×N인 체스판에서 진행되고, 사용하는 말의 개수는 K개이다. 말은 원판모양이고, 하

www.acmicpc.net

체스판과 말을 이용해서 만든 새로운게임2!

문제를 읽고 사실 요구하는 조건을 정확히 구현한다면 곧 잘 풀릴거라고 생각했다... hahaha 😝

 

우선

  1. 각 맵의 한 칸마다 어떤 숫자의 어떤 체스 말들이 쌓여있는 지와 맵의 색깔
  2. 각 말의 위치와 방향

등을 기억하고 있어야 했다.

 

그렇기 때문에 1,2번을 각각 map, piece의 구조체로 선언하고 chessPiece와 chessMap의 배열을 선언해 주었다.

 

OneTurn 함수가 '-1' 를 return 하면 그것은 더 이상 턴을 진행할 수 없는 의미이기 때문에 턴 횟수를 출력한 후 main이 종료된다.

OneTurn 함수 내에서는 move 함수를 호출하는데 이는 체스말을 옮기는 작업을 한다. 만일 옮기는 칸의 색이 파란색이라면 방향을 바꾸어주는 작업을 진행한다.

switch 문으로 구현을 했는데 지금 생각해보니 배열을 생성해 값을 바꿔주었어도 됐을 것 같다.

move 에서는 색깔을 판단하고, 해당 말과 위에 쌓여있는 말까지 함께 옮겨주는 작업을 진행했다.

 

 


#include <deque>
#include <iostream>
#include <stack>
#include <vector>
    using namespace std;
using pii = pair<int, int>;

typedef struct map {
    int color;
    deque<int> pieces;
} Map;

typedef struct piece {
    int x, y;
    int dir;
} Piece;

Piece chessPiece[11];
Map chessMap[16][16];
int N, K;
int dx[] = { 0, 0, 0, -1, 1 };
int dy[] = { 0, 1, -1, 0, 0 };

int move(int color, int i)
{
    int x = chessPiece[i].x;
    int y = chessPiece[i].y;
    int s = chessMap[x][y].pieces.size();
    int d = chessPiece[i].dir;
    int nx = x + dx[d];
    int ny = y + dy[d];

    int p = 0;
    for (int k = 0; k < s; k++) {
        if (chessMap[x][y].pieces[k] == i) {
            p = k;
            break;
        }
    }
    if (color == 0) {
        int a = p;
        for (a = p; a < s; a++) {
            int num = chessMap[x][y].pieces[a];
            chessMap[nx][ny].pieces.push_back(num);
            chessPiece[num].x = nx;
            chessPiece[num].y = ny;
        }
        p = a - p;
        while (p--)
            chessMap[x][y].pieces.pop_back();
    } else if (color == 1) {
        int a = p;
        for (a = s - 1; a >= p; a--)
        {
            int num = chessMap[x][y].pieces[a];
            chessMap[nx][ny].pieces.push_back(num);
            chessPiece[num].x = nx;
            chessPiece[num].y = ny;
        }
        p = s - p;
        while ((p--))
            chessMap[x][y].pieces.pop_back();
    }

    if (chessMap[nx][ny].pieces.size() >= 4)
        return -1;
    return 0;
}

int OneTurn()
{
    for (int i = 1; i <= K; i++) {
        int d = chessPiece[i].dir;
        int nx = chessPiece[i].x + dx[d];
        int ny = chessPiece[i].y + dy[d];
        int check = 0;
        int color = chessMap[nx][ny].color;
        if (nx <= 0 || ny <= 0 || nx >= N + 1 || ny >= N + 1)
            color = 2;
        // white
        switch (color) {
        case 0:
            check = move(color, i);
            break;
        case 1:
            check = move(color, i);
            break;
        default: {
            switch (d) {
            case 1:
                chessPiece[i].dir = 2;
                break;
            case 2:
                chessPiece[i].dir = 1;
                break;
            case 3:
                chessPiece[i].dir = 4;
                break;
            case 4:
                chessPiece[i].dir = 3;
                break;
            }
            d = chessPiece[i].dir;
            nx = chessPiece[i].x + dx[d];
            ny = chessPiece[i].y + dy[d];
            color = chessMap[nx][ny].color;
            if (chessMap[nx][ny].color == 3 || nx <= 0 || ny <= 0 || nx >= N + 1 || ny >= N + 1)
                break;

            check = move(color, i);
        }
        }
        if (check == -1)
            return -1;
    }

    return 1;

    // if 4개이상 쌓이는 순간
}
int main()
{
    // inputs
    cin >> N >> K;

    for (int i = 1; i <= N; i++)
        for (int j = 1; j <= N; j++) {
            cin >> chessMap[i][j].color;
        }

    for (int i = 1; i <= K; i++) {
        int x, y, d;
        cin >> x >> y >> d;
        chessPiece[i].x = x;
        chessPiece[i].y = y;
        chessPiece[i].dir = d;
        chessMap[x][y].pieces.push_back(i);
    }
    int ans = 0;
    while (true) {
        ans++;
        if (OneTurn() == -1)
            break;
        if (ans > 1000) {
            cout << -1 << "\n";
            return 0;
        }
    }
    cout << ans << "\n";

    return 0;
}

 

반응형

댓글