본문 바로가기
백준 알고리즘/구현

새로운 게임 2 C++

by paysmile 2021. 3. 19.

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

 

17837번: 새로운 게임 2

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

www.acmicpc.net

 

#include <iostream>
#include <vector>
#include <cstring>

using namespace std;
int n, k;
int map[13][13]; // 0:흰색, 1:빨간색, 2:파란색
struct H { int x, y, dir; }; // 1:오, 2:왼, 3:위, 4:아래
vector<H> horse;
vector<int> num[13][13]; // 칸마다 말의 개수 저장
struct MOVE { int x, y; };
MOVE mv[4] = { {0,1}, {0,-1}, {-1,0}, {1,0} };

void MoveWhite(int index, int mi, int mj) {
	int exist = 0;
	vector<H> temp_horse = horse;

	for (int i = 0; i < num[horse[index].x][horse[index].y].size(); i++) {
		if (num[horse[index].x][horse[index].y][i] == index) {
			exist = i;
			break;
		}
	}

	int count = 0;
	int start = exist;
	for (; exist < num[horse[index].x][horse[index].y].size(); exist++) {
		num[mi][mj].push_back(num[horse[index].x][horse[index].y][exist]);
		temp_horse[num[horse[index].x][horse[index].y][exist]] = { mi,mj,horse[num[horse[index].x][horse[index].y][exist]].dir };
		count += 1;
	}
	for(count; count>0; count--)
		num[horse[index].x][horse[index].y].erase(num[horse[index].x][horse[index].y].begin() + start);
	horse = temp_horse;
}

void MoveRed(int index, int mi, int mj) {
	int exist = 0;
	vector<H> temp_horse = horse;

	for (int i = 0; i < num[horse[index].x][horse[index].y].size(); i++) {
		if (num[horse[index].x][horse[index].y][i] == index) {
			exist = i;
			break;
		}
	}

	int count = 0;
	int start = exist;
	for (int i = num[horse[index].x][horse[index].y].size() - 1; exist <= i; i--) {
		num[mi][mj].push_back(num[horse[index].x][horse[index].y][i]);
		temp_horse[num[horse[index].x][horse[index].y][i]] = { mi,mj,horse[num[horse[index].x][horse[index].y][i]].dir };
		count += 1;
	}
	for (count; count > 0; count--)
		num[horse[index].x][horse[index].y].erase(num[horse[index].x][horse[index].y].begin() + start);
	horse = temp_horse;
}

void MoveBlue(int index, int mi, int mj) {
	//방향 바꾸기
	if (horse[index].dir == 0)	horse[index].dir = 1;
	else if (horse[index].dir == 1)	horse[index].dir = 0;
	else if (horse[index].dir == 2)	horse[index].dir = 3;
	else if (horse[index].dir == 3)	horse[index].dir = 2;
	
	int movei, movej;
	//움직인 위치 구하기
	if (horse[index].dir == 0) {
		movei = horse[index].x + mv[horse[index].dir].x;
		movej = horse[index].y + mv[horse[index].dir].y;
	}
	else if (horse[index].dir == 1) {
		movei = horse[index].x + mv[horse[index].dir].x;
		movej = horse[index].y + mv[horse[index].dir].y;
	}
	else if (horse[index].dir == 2) {
		movei = horse[index].x + mv[horse[index].dir].x;
		movej = horse[index].y + mv[horse[index].dir].y;
	}
	else if (horse[index].dir == 3) {
		movei = horse[index].x + mv[horse[index].dir].x;
		movej = horse[index].y + mv[horse[index].dir].y;
	}

	//다음칸이 파란칸이거나 경계 벗어나면 정지
	if (movei <= 0 || movei >n || movej <= 0 || movej >n || map[movei][movej] == 2) {
		return;
	}
	//아니라면 이동
	if (map[movei][movej] == 0)
		MoveWhite(index, movei, movej);
	else if (map[movei][movej] == 1)
		MoveRed(index, movei, movej);
}

void MoveHorse(int index) {
	int movei, movej;

	if (horse[index].dir == 0) {
		movei = horse[index].x + mv[horse[index].dir].x;
		movej = horse[index].y + mv[horse[index].dir].y;
	}
	else if (horse[index].dir == 1) {
		movei = horse[index].x + mv[horse[index].dir].x;
		movej = horse[index].y + mv[horse[index].dir].y;
	}
	else if (horse[index].dir == 2) {
		movei = horse[index].x + mv[horse[index].dir].x;
		movej = horse[index].y + mv[horse[index].dir].y;
	}
	else if (horse[index].dir == 3) {
		movei = horse[index].x + mv[horse[index].dir].x;
		movej = horse[index].y + mv[horse[index].dir].y;
	}

	if (movei <= 0 || movei >n || movej <= 0 || movej >n)
		MoveBlue(index, movei, movej);
	else {
		if (map[movei][movej] == 0)
			MoveWhite(index, movei, movej);
		else if (map[movei][movej] == 1)
			MoveRed(index, movei, movej);
		else if (map[movei][movej] == 2)
			MoveBlue(index, movei, movej);
	}
}

bool CheckHorse() {
	bool flag = true;

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			if (num[i][j].size() >= 4) {
				flag = false;
				return flag;
			}
		}
	}

	return flag;
}

int main(void) {
	int answer = 0;

	cin >> n >> k;

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			cin >> map[i][j];
		}
	}

	for (int i = 0; i < k; i++) {
		int x, y, d;
		cin >> x >> y >> d;
		horse.push_back({ x,y,d-1 });
		num[x][y].push_back(i);
	}

	bool flag = true;
	while (flag == true && answer <= 1000) {
		for (int i = 0; i < k; i++) {
			MoveHorse(i);
			if (CheckHorse() == false) {
				flag = false;
				break;
			}
		}
		answer += 1;
	}
	if (answer > 1000)
		cout << -1 << endl;
	else
		cout << answer << endl;

	return 0;
}

'백준 알고리즘 > 구현' 카테고리의 다른 글

낚시왕 C++  (0) 2021.04.11
마법사 상어와 토네이도 C++  (0) 2021.04.06
주사위 윷놀이 C++  (0) 2021.03.10
모노미노도미노 2  (0) 2021.03.08
어른 상어 C++  (0) 2021.03.04