티스토리 뷰


[BOJ 17837(G2) 리뷰]

2차원 벡터를 이용해 풀었다.

조건에 주어진 대로 구현하면 된다. 다만 이동하려는 곳이 파란색이거나 범위를 벗어날 경우 방향을 바꿔주는 작업을 좀 신경써야 한다.

말들이 이동하는 방법은 가장 간단한 방법을 사용했다. 이동하기전에 현재 위치에 있는 말들을 탐색하면서 남아있어야 할 말들과 이동해야 할 말들을 각각의 벡터에 넣은 후, 이동시키면 된다. 만약 이동하고자 하는곳이 빨간색이라고 하면 이동해야 할 말들을 넣은 벡터만 reverse해주면 된다.

방향을 바꾸는 작업은 방향을 바꾼후에 다시 한 칸을 이동해야 한다는 조건때문에, 방향을 바꾸고 반복문 i의 값을 감소시켜 한번 더 반복문을 돌게 했다. 이때 이미 한번 방향을 바꾼적 이 있다면 그대로 움직이지 말아야 한다.

구현은 쓱쓱했는데 정말 어처구니 없는 실수를 해서 시간을 오래 잡아먹었던 문제이다.
(디버깅을 위해 중간에 printf를 껴놨는데 그걸 안빼고 계속 이게 왜틀리지? 를 30분 했다.ㅠ

/*
	21.01.03
	BOJ : 17837 새로운 게임 2 (https://www.acmicpc.net/problem/17837)
	구현
*/
#include <bits/stdc++.h>
using namespace std;

typedef struct info {
	int r;
	int c;
	int dir;
}info;
int N, K;
int board[14][14];
vector <int> item[14][14];
vector <info> idx;

int dx[5] = {0, 0,0,-1,1 };
int dy[5] = {0, 1,-1,0,0 };

int main() {
	cin.tie(0);
	ios::sync_with_stdio(0);
	
	cin >> N >> K;

	for (int i = 0; i <= N; i++) {
		for (int j = 0; j <= N; j++) {
			if (i == 0 || j == 0) {
				board[i][j] = -1;
			}else
				cin >> board[i][j];
		}
	}

	idx.push_back({ 0,0,0 });
	for (int i = 1; i <= K; i++) {
		int r, c, dir;
		cin >> r >> c >> dir;
		idx.push_back({ r,c,dir });
		item[r][c].push_back(i);
	}

	int turn = 0;
	int end = 0;
	int blue = 0;
	while (true) {
		turn++;
		if (turn >= 1000) break;
		for (int i = 1; i <= K; i++) {
			auto cur = idx[i];

			int nr = cur.r + dx[cur.dir];
			int nc = cur.c + dy[cur.dir];

			if (board[nr][nc] == 2 || (nr<1 || nc <1 || nr>N || nc >N)) {
				if (blue) {
					blue = 0;
					continue;
				}
					
				if (cur.dir == 1) {
					idx[i].dir = 2;
				}
				else if (cur.dir == 2) {
					idx[i].dir = 1;
				}
				else if (cur.dir == 3) {
					idx[i].dir = 4;
				}
				else if (cur.dir == 4) {
					idx[i].dir = 3;
				}

				if (!blue) {
					i--;
					blue = 1;
				}
			}else if (board[nr][nc] == 0) { //white
				blue = 0;
				int size = item[cur.r][cur.c].size();
				vector <int> remain;
				vector <int> add;

				int check = 0;
				for (int j = 0; j < size; j++) {
					if (i == item[cur.r][cur.c][j]) {
						check = 1;
					}
					if (!check) {
						remain.push_back(item[cur.r][cur.c][j]);
					}
					else {
						add.push_back(item[cur.r][cur.c][j]);
					}
				}

				item[cur.r][cur.c].clear();
				for (int j = 0; j < remain.size(); j++) {
					item[cur.r][cur.c].push_back(remain[j]);
				}

				for (int j = 0; j < add.size(); j++) {
					item[nr][nc].push_back(add[j]);
					idx[add[j]].r = nr;
					idx[add[j]].c = nc;
				}

				if (item[nr][nc].size() >= 4) {
					end = 1;
				}
			}
			else if (board[nr][nc] == 1) {
				blue = 0;
				int size = item[cur.r][cur.c].size();
				vector <int> remain;
				vector <int> add;

				int check = 0;
				for (int j = 0; j < size; j++) {
					if (i == item[cur.r][cur.c][j]) {
						check = 1;
					}
					if (!check) {
						remain.push_back(item[cur.r][cur.c][j]);
					}
					else {
						add.push_back(item[cur.r][cur.c][j]);
					}
				}

				reverse(add.begin(), add.end());

				item[cur.r][cur.c].clear();
				for (int j = 0; j < remain.size(); j++) {
					item[cur.r][cur.c].push_back(remain[j]);
				}

				for (int j = 0; j < add.size(); j++) {
					item[nr][nc].push_back(add[j]);
					idx[add[j]].r = nr;
					idx[add[j]].c = nc;
				}

				if (item[nr][nc].size() >= 4) {
					end = 1;
				}
			}
			

			if (end) {
				cout << turn;
				return 0;
			}
		}
		
	}

	cout << -1;

}

'알고리즘 풀이 > 시뮬레이션' 카테고리의 다른 글

BOJ : 3425 고스택  (0) 2021.01.11
BOJ : 19238 스타트 택시  (0) 2021.01.08
BOJ : 20055 컨베이어 벨트 위의 로봇  (0) 2021.01.02
BOJ : 16235 나무 재테크  (0) 2021.01.01
BOJ : 14890 경사로  (0) 2020.12.30
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
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
글 보관함