[삼성] 17780 새로운 게임
2019. 10. 28. 17:16ㆍ알고리즘/백준
삼성 낚시왕과 유사한 시뮬레이션 문제지만 좀 더 어려운 문제라고 생각된다. 자료구조 선택이 중요한데 말의 순서를 위해서 앞과 뒤로 모두 데이터가 들어가기 때문에 덱을 이용했다. 말 순서대로 시뮬레이션을 했으며, 이동할 때마다 밑의 말이 바뀔 수 있으니 체크하는 것이 매우 중요하다
문제: https://www.acmicpc.net/problem/17780
깃허브주소: https://github.com/surinoel/boj/blob/master/17780.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <deque> | |
#include <iostream> | |
using namespace std; | |
struct MAL { | |
int num, dir; | |
MAL(int num = 0, int dir = 0) | |
: num(num), dir(dir) {} | |
}; | |
struct MatInfo { | |
int color; | |
deque<MAL> dq; | |
}; | |
struct MALInfo { | |
int x, y, dir; | |
bool bot; | |
MALInfo(int x = 0, int y = 0, int dir = 0, bool bot = false) | |
: x(x), y(y), dir(dir), bot(bot) {} | |
}; | |
MatInfo mat[12][12]; | |
MALInfo MalInfo[11]; | |
int dx[5] = { 0, 0, 0, -1, 1 }; | |
int dy[5] = { 0, 1, -1, 0, 0 }; | |
void move_color0(int x, int y, int tx, int ty) { | |
while (mat[x][y].dq.size() > 0) { | |
int tnum, tdir; | |
tnum = mat[x][y].dq.back().num; | |
tdir = mat[x][y].dq.back().dir; | |
MalInfo[tnum].x = tx; | |
MalInfo[tnum].y = ty; | |
MalInfo[tnum].dir = tdir; | |
MalInfo[tnum].bot = false; | |
mat[tx][ty].dq.push_front(MAL(tnum, tdir)); | |
mat[x][y].dq.pop_back(); | |
} | |
MalInfo[mat[tx][ty].dq.back().num].bot = true; | |
} | |
void move_color1(int x, int y, int tx, int ty) { | |
while (mat[x][y].dq.size() > 0) { | |
int tnum, tdir; | |
tnum = mat[x][y].dq.front().num; | |
tdir = mat[x][y].dq.front().dir; | |
MalInfo[tnum].x = tx; | |
MalInfo[tnum].y = ty; | |
MalInfo[tnum].dir = tdir; | |
MalInfo[tnum].bot = false; | |
mat[tx][ty].dq.push_front(MAL(tnum, tdir)); | |
mat[x][y].dq.pop_front(); | |
} | |
MalInfo[mat[tx][ty].dq.back().num].bot = true; | |
} | |
void move_color2(int dir, int j, int n, int x, int y, int tx, int ty) { | |
if (dir == 1) dir = 2; | |
else if (dir == 2) dir = 1; | |
else if (dir == 3) dir = 4; | |
else if (dir == 4) dir = 3; | |
mat[x][y].dq.back().dir = dir; | |
MalInfo[j].dir = dir; | |
tx = x + dx[dir]; | |
ty = y + dy[dir]; | |
if (tx < 0 || ty < 0 || tx > n - 1 || ty > n - 1 || mat[tx][ty].color == 2) { | |
if (dir == 1) dir = 2; | |
else if (dir == 2) dir = 1; | |
else if (dir == 3) dir = 4; | |
else if (dir == 4) dir = 3; | |
mat[x][y].dq.back().dir = dir; | |
MalInfo[j].dir = dir; | |
} | |
else if (mat[tx][ty].color == 0) { | |
move_color0(x, y, tx, ty); | |
} | |
else if (mat[tx][ty].color == 1) { | |
move_color1(x, y, tx, ty); | |
} | |
} | |
int main(void) { | |
ios_base::sync_with_stdio(false); | |
cin.tie(nullptr); | |
int n, m; | |
cin >> n >> m; | |
for (int i = 0; i < n; i++) { | |
for (int j = 0; j < n; j++) { | |
cin >> mat[i][j].color; | |
} | |
} | |
for (int i = 0; i < m; i++) { | |
int x, y, d; | |
cin >> x >> y >> d; | |
x -= 1, y -= 1; | |
mat[x][y].dq.push_back(MAL(i + 1, d)); | |
MalInfo[i + 1] = MALInfo(x, y, d, true); | |
} | |
int ans = -1; | |
for (int i = 1; ; i++) { | |
if (i > 1000) break; | |
for (int j = 1; j <= m; j++) { | |
if (MalInfo[j].bot) { | |
int dir = MalInfo[j].dir; | |
int x = MalInfo[j].x; | |
int y = MalInfo[j].y; | |
int tx = x + dx[dir]; | |
int ty = y + dy[dir]; | |
if (tx < 0 || ty < 0 || tx > n - 1 || ty > n - 1) { | |
move_color2(dir, j, n, x, y, tx, ty); | |
} | |
else { | |
int color = mat[tx][ty].color; | |
if (color == 0) { | |
move_color0(x, y, tx, ty); | |
} | |
else if (color == 1) { | |
move_color1(x, y, tx, ty); | |
} | |
else if (color == 2) { | |
move_color2(dir, j, n, x, y, tx, ty); | |
} | |
} | |
} | |
} | |
bool ok = false; | |
for (int u = 0; u < n; u++) { | |
for (int v = 0; v < n; v++) { | |
if (mat[u][v].dq.size() >= 4) { | |
ok = true; | |
} | |
} | |
} | |
if (ok) { | |
ans = i; | |
break; | |
} | |
} | |
cout << ans << '\n'; | |
return 0; | |
} |
'알고리즘 > 백준' 카테고리의 다른 글
[삼성] 17825 주사위 윷놀이 (1) | 2019.11.05 |
---|---|
2042 구간 합 구하기 (0) | 2019.10.30 |
[삼성] 17822 원판돌리기 (0) | 2019.10.26 |
[삼성] 17779 게리멘더링 2 (0) | 2019.10.24 |
16933 벽 부수고 이동하기 3 (0) | 2019.10.22 |