CS/Algorithm

[BOJ][C++] 17837 새로운 게임2

별토끼. 2020. 2. 13. 12:49
반응형
문제

https://www.acmicpc.net/problem/17837

 

17837번: 새로운 게임 2

재현이는 주변을 살펴보던 중 체스판과 말을 이용해서 새로운 게임을 만들기로 했다. 새로운 게임은 크기가 N×N인 체스판에서 진행되고, 사용하는 말의 개수는 K개이다. 말은 원판모양이고, 하나의 말 위에 다른 말을 올릴 수 있다. 체스판의 각 칸은 흰색, 빨간색, 파란색 중 하나로 색칠되어있다. 게임은 체스판 위에 말 K개를 놓고 시작한다. 말은 1번부터 K번까지 번호가 매겨져 있고, 이동 방향도 미리 정해져 있다. 이동 방향은 위, 아래, 왼쪽, 오른쪽

www.acmicpc.net

풀이

문제를 잘 숙지해야 실수없이 풀 수 있습니다. 자꾸 하나씩 빼먹어서 시간이 좀 걸렸습니다. 흰색과 빨간색이 순서를 바꿔줘야해서 덱을 썼는데 계속 수정하면서 풀다보니 코드가 지저분해졌네요. 문제를 잘 파악하고 구조적으로 설계하는게 중요하다고 느꼈습니다.

제가 빠뜨린 부분은 현재 인덱스까지만 쌓인 값이 이동한다는 것이었습니다. 만약, 1,2,3,4 가 쌓여있는 경우 인덱스가 2일 경우 1은 제자리를 지켜야합니다. 가장 중요한 부분인데 빠뜨리고 있었어요.

흰색 : 다음 칸으로 이동, 이동할 칸에 말이 있으면 그 위에 순서대로 쌓습니다.

빨간색 : 다음 칸으로 이동, 이동할 칸에 반대로 쌓아줍니다.

파랑색 : 이동할 방향을 반대로 바꿈, 만약 방향을 바꾼 뒤 이동할 곳이 파랑이거나 범위가 벗어날 경우 방향만 바꿔줍니다.

말이 4개 이상 쌓이면 그대로 종료하고 t를 결과값에 넣습니다.

코드
#include <iostream>
#include <deque>
#include <vector>
using namespace std;

int n, k, answer=-1;
int map[13][13];
deque<int> v[13][13];
int chess[11][3];
int dx[] = { 0,0,0,-1,1 };
int dy[] = { 0,1,-1,0,0 };

int main() {
	cin >> n >> k;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			cin >> map[i][j];
		}
	}
	for (int i = 1; i <= k; i++) {
		//행, 열, 이동번호, 우좌상하
		cin >> chess[i][0] >> chess[i][1] >> chess[i][2];
		v[chess[i][0]][chess[i][1]].push_back(i);
 	}
	int t = 0;
	bool isFin = false;
	while (t<=1000) {
		//모든 턴 돌기
		for (int i = 1; i <= k; i++) {
			int x = chess[i][0];
			int y = chess[i][1];
			int dir = chess[i][2];
			int nx = x + dx[dir];
			int ny = y + dy[dir];
			if (nx <= 0 || ny <= 0 || nx > n || ny > n || map[nx][ny] == 2) {
				if (dir == 1 || dir == 3) {
					dir += 1;
				}
				else {
					dir -= 1;
				}
				nx = x + dx[dir];
				ny = y + dy[dir];
				if (map[nx][ny] != 2 && nx>0 && ny>0 && nx<=n && ny<=n) {
					if (map[nx][ny] == 0) {
						int sz = v[x][y].size();
						deque<int> tmpv;
						for (int j = 0; j < sz; j++) {
							int idx = v[x][y].back();
							tmpv.push_back(idx);
							v[x][y].pop_back();
							chess[idx][0] = nx;
							chess[idx][1] = ny;
							if (i == idx) {
								break;
							}
						}
						while (!tmpv.empty()) {
							v[nx][ny].push_back(tmpv.back());
							tmpv.pop_back();
						}
					}
					else if (map[nx][ny] == 1) {
						int sz = v[x][y].size();
						for (int j = 0; j < sz; j++) {
							int idx = v[x][y].back();

							v[nx][ny].push_back(idx);
							v[x][y].pop_back();
							chess[idx][0] = nx;
							chess[idx][1] = ny;
							if (i == idx) {
								break;
							}
						}
					}
				}
				else {
					nx = x;
					ny = y;
				}
				chess[i][0] = nx;
				chess[i][1] = ny;
				chess[i][2] = dir;
			}
			else if (map[nx][ny] == 0) {
				int sz = v[x][y].size();
				deque<int> tmpv;
				for (int j = 0; j < sz; j++) {
					int idx = v[x][y].back();
					tmpv.push_back(idx);
					v[x][y].pop_back();
					chess[idx][0] = nx;
					chess[idx][1] = ny;
					if (i == idx) {
						break;
					}
				}
				while (!tmpv.empty()) {
					v[nx][ny].push_back(tmpv.back());
					tmpv.pop_back();
				}
			}
			else if (map[nx][ny] == 1) {
				int sz = v[x][y].size();
				for (int j = 0; j < sz; j++) {
					int idx = v[x][y].back();
					
					v[nx][ny].push_back(idx);
					v[x][y].pop_back();
					chess[idx][0] = nx;
					chess[idx][1] = ny;
					if (i == idx) {
						break;
					}
				}
			}
			if (v[nx][ny].size() >= 4) {
				isFin = true;
				break;
			}
		}
		
		if (isFin) {
			answer = t+1;
			break;
		}
		t++;
	}
	cout << answer;
}
반응형