-
백준 17780번 새로운 게임PS 2020. 1. 29. 23:56
https://www.acmicpc.net/problem/17780
17780번: 새로운 게임
재현이는 주변을 살펴보던 중 체스판과 말을 이용해서 새로운 게임을 만들기로 했다. 새로운 게임은 크기가 N×N인 체스판에서 진행되고, 사용하는 말의 개수는 K개이다. 말은 원판모양이고, 하나의 말 위에 다른 말을 올릴 수 있다. 체스판의 각 칸은 흰색, 빨간색, 파란색 중 하나로 색칠되어있다. 게임은 체스판 위에 말 K개를 놓고 시작한다. 말은 1번부터 K번까지 번호가 매겨져 있고, 이동 방향도 미리 정해져 있다. 이동 방향은 위, 아래, 왼쪽, 오른쪽
www.acmicpc.net
<접근방법>
말이 겹치는 상황에서 말을 관리하려면 2차원배열의 벡터가 필요합니다.
말이 4개 이상 쌓이면 게임을 종료하는 것입니다.
딱 4개가 아닙니다..
다른 케이스임에도 반복적인 행동을 요구하는 부분이 있습니다.
생각해서 구현하면 코드가 이뻐집니다...
<코드>
#include <iostream> #include <algorithm> #include <vector> #include <stack> using namespace std; typedef enum _COLOR { WHITE = 0, RED = 1, BLUE = 2 }COLOR; struct state { int y, x, d; }; int n, k; int color[12][12]; //0 흰색 1 빨간색 2 파란색 vector<int> w[12][12]; state horse[10]; int dy[4] = { 0, 0, -1, 1 }; int dx[4] = { 1, -1, 0, 0 }; bool check_end() { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (w[i][j].size() >= 4) return true; } } return false; } void change_dir(int h, int d) { switch (d) { case 0: horse[h].d = 1; break; case 1: horse[h].d = 0; break; case 2: horse[h].d = 3; break; case 3: horse[h].d = 2; break; default: break; } } void move(int h, int y, int x, int ny, int nx, int d, int col) { //색깔에 따른 행동지침 switch (col) { //흰색 case WHITE: for (int i = 0; i < w[y][x].size(); i++) { int tmp = w[y][x][i]; horse[tmp].y = ny; horse[tmp].x = nx; w[ny][nx].push_back(tmp); } w[y][x].clear(); break; //빨간색 case RED: reverse(w[y][x].begin(), w[y][x].end()); for (int i = 0; i < w[y][x].size(); i++) { int tmp = w[y][x][i]; horse[tmp].y = ny; horse[tmp].x = nx; w[ny][nx].push_back(tmp); } w[y][x].clear(); break; //파란색 //방향을 바꾼 후 이동한다. //이때 방향을 바꾼 후 이동하는 칸이 파랑칸이거나 범위 밖인 경우에 유의한다. case BLUE: change_dir(h, d); d = horse[h].d; ny = y + dy[d]; nx = x + dx[d]; //파랑색을 만나서 방향을 바꿨음에도 이동할 수 없는 경우 if (nx < 0 || nx >= n || ny < 0 || ny >= n) return; if (color[ny][nx] == BLUE) return; move(h, y, x, ny, nx, d, color[ny][nx]); break; default: break; } } //말이 움직이는 것을 시뮬레이션 //종료조건은 말 4개가 겹치는 것 //말이 움직일 때마다 4개가 겹쳤는지 확인 int simul() { int res = 0; while (++res < 1000) { for (int h = 0; h < k; h++) { int y = horse[h].y; int x = horse[h].x; int d = horse[h].d; int ny = y + dy[d]; int nx = x + dx[d]; int nxt_color = color[ny][nx]; if (w[y][x][0] != h) continue; // 맨 밑이 아니면 이동할 수 없다. if (nx < 0 || nx >= n || ny < 0 || ny >= n) {// 범위 바깥일 때는 파랑과 행동지침이 같다. move(h, y, x, ny, nx, d, BLUE); } else { move(h, y, x, ny, nx, d, nxt_color); } } if (check_end())return res; } return -1; } int main() { cin >> n >> k; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cin >> color[i][j]; } } for (int i = 0; i < k; i++) { int a, b, c; cin >> a >> b >> c; a--; b--; c--; horse[i].y = a; horse[i].x = b; horse[i].d = c; w[a][b].push_back(i); } cout << simul() << '\n'; return 0; }
<느낀 점>
-
ypedef enum _COLOR {
WHITE = 0, RED = 1, BLUE = 2
}COLOR;이거 편하다
-
라운드 개념 시뮬레이션 할 때, while안에 1이 아닌 조건문을 넣어서 하면 조금 더 직관적인 느낌이다.
반응형'PS' 카테고리의 다른 글
백준 17822번 원판돌리기 (0) 2020.02.04 백준 17837번 새로운 게임2 (0) 2020.01.30 백준 15898번 피아의 아틀리에 ~신비한 대회의 연금술사~ (0) 2020.01.28 알고스팟 Quantization (0) 2020.01.24 알고스팟 원주율 외우기 PI (0) 2020.01.22