Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
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
Tags more
Archives
Today
Total
관리 메뉴

개발자 일기장.

백준 17837. 새로운 게임2 본문

취업/Algorithm.

백준 17837. 새로운 게임2

Azderica 2020. 4. 11. 00:19

새로운 게임2

 


Problem?

문제 :  https://www.acmicpc.net/problem/17837
 

17837번: 새로운 게임 2

재현이는 주변을 살펴보던 중 체스판과 말을 이용해서 새로운 게임을 만들기로 했다. 새로운 게임은 크기가 N×N인 체스판에서 진행되고, 사용하는 말의 개수는 K개이다. 말은 원판모양이고, 하나의 말 위에 다른 말을 올릴 수 있다. 체스판의 각 칸은 흰색, 빨간색, 파란색 중 하나로 색칠되어있다. 게임은 체스판 위에 말 K개를 놓고 시작한다. 말은 1번부터 K번까지 번호가 매겨져 있고, 이동 방향도 미리 정해져 있다. 이동 방향은 위, 아래, 왼쪽, 오른쪽

www.acmicpc.net

 

Solution

문제 구현 문제

  1. 흰색, 파란색, 빨간색에 경우에 맞춰서 문제를 푼다.
  2. 특히 순서를 잘 관리하면서 움직이는 것을 확인하는 것이 중요한 문제이다.

 

Code

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define MAX 12 + 1
struct knight_pos {
    int y;
    int x;
    int dir;
};

pair<int, int> dir[5] = { {0, 0}, {0, 1},{0, -1},{-1, 0},{1, 0} };
int N, K;
int board[MAX][MAX];
vector<int> order[MAX][MAX];
vector<knight_pos> knight;

bool isInRange(int y, int x) {
    if (y >= 1 && y <= N && x >= 1 && x <= N)
        return true;
    return false;
}

int main(int argc, const char* argv[]) {
    // input
    int r, c, d;
    cin >> N >> K;
    for (int i = 1; i <= N; i++)
        for (int j = 1; j <= N; j++)
            scanf("%d", &board[i][j]);
    for (int i = 0; i < K; i++) {
        scanf("%d %d %d", &r, &c, &d);
        knight.push_back({ r, c, d });
        order[r][c].push_back(i);
    }

    // solution
    int turn = 0;
    while (true) {
        if (turn > 1000)
            break;
        turn++;
        for (int i = 0; i < K; i++) {
            int curY = knight[i].y;
            int curX = knight[i].x;
            int nextY = curY + dir[knight[i].dir].first;
            int nextX = curX + dir[knight[i].dir].second;

            // 다음칸이 나가는 경우이거나 파란색인 경우
            if (!isInRange(nextY, nextX) || board[nextY][nextX] == 2) {
                if (knight[i].dir == 1 || knight[i].dir == 2)    // 순서바꾸기
                    knight[i].dir = 3 - knight[i].dir;
                else
                    knight[i].dir = 7 - knight[i].dir;
                nextY = curY + dir[knight[i].dir].first;
                nextX = curX + dir[knight[i].dir].second;
            }

            // 다음칸이 나가거나 파란색인 경우, 다시
            if (!isInRange(nextY, nextX) || board[nextY][nextX] == 2)
                continue;
            else if (board[nextY][nextX] == 0) {  // 하얀색
                int idx = -1;
                for (int j = 0; j < order[curY][curX].size(); j++) {
                    int t = order[curY][curX][j];
                    if (t == i)
                        idx = j;
                    if (idx == -1) continue;     // 없는 경우

                    knight[t].y = nextY;
                    knight[t].x = nextX;
                    order[nextY][nextX].push_back(t);
                    if (order[nextY][nextX].size() >= 4) {
                        cout << turn << "\n";
                        return 0;
                    }
                }
                int cnt = (int)order[curY][curX].size();
                for (int j = idx; j < cnt; j++)
                    order[curY][curX].pop_back();
            }
            else {                               // 빨간색
                int idx = -1;
                for (int j = (int)order[curY][curX].size() - 1; j >= 0; j--) {
                    int t = order[curY][curX][j];
                    if (t == i) {
                        idx = j;
                        break;
                    }
                }
                for (int j = (int)order[curY][curX].size() - 1; j >= idx; j--) {
                    int t = order[curY][curX][j];
                    knight[t].y = nextY;
                    knight[t].x = nextX;
                    order[nextY][nextX].push_back(t);
                    if (order[nextY][nextX].size() >= 4) {
                        cout << turn << "\n";
                        return 0;
                    }
                }
                int cnt = (int)order[curY][curX].size();
                for (int j = idx; j < cnt; j++)
                    order[curY][curX].pop_back();
            }
        }
    }
    cout << "-1\n" << "\n";

    return 0;
}

 


  • 단순 구현 문제...

 

'취업 > Algorithm.' 카테고리의 다른 글

백준 2573. 빙산  (0) 2020.05.01
[2020카카오공채] 괄호 변환  (0) 2020.04.11
백준 17140. 이차원배열과 연산  (0) 2020.04.11
백준 15684. 사다리 조작  (0) 2020.04.11
백준 17472. 다리만들기2  (0) 2020.04.10