알고리즘/BOJ

[BOJ] 17837. 새로운 게임 2

재담 2022. 2. 7. 20:25

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

 

17837번: 새로운 게임 2

재현이는 주변을 살펴보던 중 체스판과 말을 이용해서 새로운 게임을 만들기로 했다. 새로운 게임은 크기가 N×N인 체스판에서 진행되고, 사용하는 말의 개수는 K개이다. 말은 원판모양이고, 하

www.acmicpc.net

#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>

using namespace std;

struct Unit {
	int r;
	int c;
	int dir;
};

int pan[13][13];
vector<int> units[13][13];
vector<Unit> location;
int N, K;
int d[5][2] = { {0,0},{0,1},{0,-1},{-1,0}, {1,0} };

void moveToWhite(int index, int r, int c, int nr, int nc) {
	for (auto it = find(units[r][c].begin(), units[r][c].end(), index); it != units[r][c].end();) {
		units[nr][nc].push_back(*it);
		location[*it].r = nr;
		location[*it].c = nc;
		it = units[r][c].erase(it);
	}
}

void moveToRed(int index, int r, int c, int nr, int nc) {
	moveToWhite(index, r, c, nr, nc);
	reverse(find(units[nr][nc].begin(), units[nr][nc].end(), index), units[nr][nc].end());
}

void moveToBlue(int index, int r, int c) {
	if (location[index].dir == 1) {
		location[index].dir = 2;
	}
	else if (location[index].dir == 2) {
		location[index].dir = 1;
	}
	else if (location[index].dir == 3) {
		location[index].dir = 4;
	}
	else {
		location[index].dir = 3;
	}

	int nr = r + d[location[index].dir][0];
	int nc = c + d[location[index].dir][1];

	if (nr == 0 || nr == N + 1 || nc == 0 || nc == N + 1) {
		return;
	}

	if (pan[nr][nc] == 0) {
		moveToWhite(index, r, c, nr, nc);
	}
	else if (pan[nr][nc] == 1) {
		moveToRed(index, r, c, nr, nc);
	}
}

int main() {
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> N >> K;
	for (int i = 1; i <= N; ++i) {
		for (int j = 1; j <= N; ++j) {
			cin >> pan[i][j];
		}
	}

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

	int turn = 1;
	while (turn <= 1000) {
		for (int i = 1; i <= K; ++i) {
			Unit unit = location[i];
			int r = unit.r;
			int c = unit.c;
			int nr = r + d[unit.dir][0];
			int nc = c + d[unit.dir][1];

			if (nr == 0 || nr == N + 1 || nc == 0 || nc == N + 1 || pan[nr][nc] == 2) {
				moveToBlue(i, r, c);
			}
			else if (pan[nr][nc] == 0) {
				moveToWhite(i, r, c, nr, nc);
			}
			else {
				moveToRed(i, r, c, nr, nc);
			}

			for (int j = 1; j <= K; ++j) {
				unit = location[j];
				r = unit.r;
				c = unit.c;
				if (units[r][c].size() >= 4) {
					cout << turn << endl;
					return 0;
				}
			}
		}

		++turn;
	}

	cout << -1 << endl;
}
  • 단순 시뮬레이션
  • 다음 움직일 위치에 따라 함수 구현 후 반복문 시행

'알고리즘 > BOJ' 카테고리의 다른 글

[BOJ] 17136. 색종이 붙이기  (0) 2022.02.15
[BOJ] 16137. 견우와 직녀  (0) 2022.02.10
[BOJ] 2749. 피보나치 수 3  (0) 2022.02.09
[BOJ] 2042. 구간 합 구하기  (0) 2022.02.08
[BOJ] 3197. 백조의 호수  (0) 2022.02.06