알고리즘/BOJ
[BOJ] 17837번 새로운 게임2
간타타
2020. 8. 4. 02:27
https://www.acmicpc.net/problem/17837
17837번: 새로운 게임 2
재현이는 주변을 살펴보던 중 체스판과 말을 이용해서 새로운 게임을 만들기로 했다. 새로운 게임은 크기가 N×N인 체스판에서 진행되고, 사용하는 말의 개수는 K개이다. 말은 원판모양이고, 하�
www.acmicpc.net
아이디어
1, 문제의 조건에 따라서 시뮬레이션을 만들어 주웠다.
2, 시뮬레이션을 생성할 때 처리의 과정을 2 분류로 나누었다.
1) 위치를 이동시켰을 때 파란색 범위인지, 판을 벗어났는지의 여부를 먼저 판단하고 만약 그러한 상황이 되었다면 1차적으로 처리를 해 줌(방향을 반대로)
2) 첫 번째 처리과정을 거친 후 범위를 벗어난 경우/파란색 부분, 빨간색 부분, 흰색 부분에 따라 조건에 맞게 처리를 해 준다.
주의할 점
1, 종료 조건 : 체스판의 한 구역에 4개 이상의 말이 모여있을 때
2, 빨간색 부분일 때에는 이동을 시킨 말의 쌓여있는 순서를 바꾸어야 함
3, 1000 초과의 경우를 넘어갈 때에는 -1을 출력
#include <cstdio>
#include <vector>
#include <deque>
using namespace std;
typedef struct unit_location {
int r;
int c;
int dir;
}unit_location;
int map[20][20];
int temp_map[20][20];
vector<deque<int>> unit_map[20];
vector<unit_location> location;
int dr[4] = { 0,0,-1,1 };
int dc[4] = { 1,-1,0,0 };
int n, k;
bool simulation(int unit_index) {
deque<int> move_unit;
int nr, nc;
//유닛에 대한 정보를 가져옴
unit_location search = location[unit_index];
//유닛까지 위에 있는 것을 움직일 후보군에 저장
while (1) {
if (unit_map[search.r][search.c].back() == unit_index) {
move_unit.push_back(unit_map[search.r][search.c].back());
unit_map[search.r][search.c].pop_back();
break;
}
else {
move_unit.push_back(unit_map[search.r][search.c].back());
unit_map[search.r][search.c].pop_back();
}
}
nr = search.r + dr[search.dir];
nc = search.c + dc[search.dir];
//초벌과정
if (nr < 0 || nr >= n || nc < 0 || nc >= n) {
//방향을 바꾼다
if (search.dir == 0) {
location[unit_index].dir = 1;
search.dir = 1;
nr = search.r + dr[search.dir];
nc = search.c + dc[search.dir];
}
else if (search.dir == 1) {
location[unit_index].dir = 0;
search.dir = 0;
nr = search.r + dr[search.dir];
nc = search.c + dc[search.dir];
}
else if (search.dir == 2) {
location[unit_index].dir = 3;
search.dir = 3;
nr = search.r + dr[search.dir];
nc = search.c + dc[search.dir];
}
else if (search.dir == 3) {
location[unit_index].dir = 2;
search.dir = 2;
nr = search.r + dr[search.dir];
nc = search.c + dc[search.dir];
}
}
else if (map[nr][nc] == 2) {
//방향을 바꾼다
if (search.dir == 0) {
location[unit_index].dir = 1;
search.dir = 1;
nr = search.r + dr[search.dir];
nc = search.c + dc[search.dir];
}
else if (search.dir == 1) {
location[unit_index].dir = 0;
search.dir = 0;
nr = search.r + dr[search.dir];
nc = search.c + dc[search.dir];
}
else if (search.dir == 2) {
location[unit_index].dir = 3;
search.dir = 3;
nr = search.r + dr[search.dir];
nc = search.c + dc[search.dir];
}
else if (search.dir == 3) {
location[unit_index].dir = 2;
search.dir = 2;
nr = search.r + dr[search.dir];
nc = search.c + dc[search.dir];
}
}
//메인과정
//범위를 벗어나는 경우
if (nr < 0 || nr >= n || nc < 0 || nc >= n) {
//제자리로 위치시켜줌
while (!move_unit.empty()) {
unit_map[search.r][search.c].push_back(move_unit.back());
move_unit.pop_back();
}
if (unit_map[search.r][search.c].size() >= 4) return true;
}
//파란색인 경우
else if (map[nr][nc] == 2) {
//제자리로 위치시켜줌
while (!move_unit.empty()) {
unit_map[search.r][search.c].push_back(move_unit.back());
move_unit.pop_back();
}
if (unit_map[search.r][search.c].size() >= 4) return true;
}
//흰색인 경우
else if (map[nr][nc] == 0) {
while (!move_unit.empty()) {
unit_map[nr][nc].push_back(move_unit.back());
//위치 정보를 갱신
location[move_unit.back()].r = nr;
location[move_unit.back()].c = nc;
move_unit.pop_back();
}
if (unit_map[nr][nc].size() >= 4) return true;
}
//빨간색인 경우
else if (map[nr][nc] == 1) {
//제자리로 위치시켜줌
while (!move_unit.empty()) {
unit_map[nr][nc].push_back(move_unit.front());
//위치정보를 갱신
location[move_unit.front()].r = nr;
location[move_unit.front()].c = nc;
move_unit.pop_front();
}
if (unit_map[nr][nc].size() >= 4) return true;
}
return false;
}
int main() {
deque<int> insert;
int temp;
int temp_r;
int temp_c;
int temp_dir;
int res = 0;
int check = 0;
scanf("%d %d", &n, &k);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
insert.clear();
scanf("%d", &temp);
if (temp != 0) {
map[i][j] = temp;
}
unit_map[i].push_back(insert);
}
}
location.push_back({ 0,0,0 });
for (int i = 0; i < k; i++) {
scanf("%d %d %d", &temp_r, &temp_c, &temp_dir);
unit_location insert;
insert.r = temp_r - 1;
insert.c = temp_c - 1;
insert.dir = temp_dir - 1;
location.push_back(insert);
unit_map[insert.r][insert.c].push_back(i+1);
}
while (1) {
if (res > 1000) break;
res++;
for (int i = 1; i <= k; i++) {
if (simulation(i)) {
check = 1;
break;
}
}
if (check == 1) break;
}
if (check == 0) {
printf("%d\n", -1);
}
else {
printf("%d\n", res);
}
return 0;
}