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

주사위 굴리기 2

by paysmile 2021. 12. 4.

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

 

23288번: 주사위 굴리기 2

크기가 N×M인 지도가 존재한다. 지도의 오른쪽은 동쪽, 위쪽은 북쪽이다. 지도의 좌표는 (r, c)로 나타내며, r는 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로부터 떨어진 칸의 개수이다. 가장 왼

www.acmicpc.net

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

using namespace std;

const int MAX = 22;
int n, m;
int map[MAX][MAX];
int answer = 0;
pair<int, int> loc;
int curdir = 1; //1:동, 2:서 3:남 4:북
struct MOVE { int x, y; };
MOVE mv[5] = { {-1,-1}, {0,1}, {0,-1}, {1,0}, {-1,0} };
vector<int> turn;
int value = 0;
int visited[MAX][MAX];

void MoveDice() {
	bool flag = false;

	while (flag == false) {
		int movei = loc.first + mv[curdir].x;
		int movej = loc.second + mv[curdir].y;

		if (movei >= 1 && movei <= n && movej >= 1 && movej <= m) {
			loc = make_pair(movei, movej);
			if (curdir == 1) {
				vector<int> tmp;
				tmp.push_back(turn[1]);
				tmp.push_back(turn[5]);
				tmp.push_back(turn[0]);
				tmp.push_back(turn[3]);
				tmp.push_back(turn[4]);
				tmp.push_back(turn[2]);
				turn = tmp;
			}
			else if (curdir == 2) {
				vector<int> tmp;
				tmp.push_back(turn[2]);
				tmp.push_back(turn[0]);
				tmp.push_back(turn[5]);
				tmp.push_back(turn[3]);
				tmp.push_back(turn[4]);
				tmp.push_back(turn[1]);
				turn = tmp;
			}
			else if (curdir == 3) {
				vector<int> tmp;
				tmp.push_back(turn[3]);
				tmp.push_back(turn[1]);
				tmp.push_back(turn[2]);
				tmp.push_back(turn[5]);
				tmp.push_back(turn[0]);
				tmp.push_back(turn[4]);
				turn = tmp;
			}
			else if (curdir == 4) {
				vector<int> tmp;
				tmp.push_back(turn[4]);
				tmp.push_back(turn[1]);
				tmp.push_back(turn[2]);
				tmp.push_back(turn[0]);
				tmp.push_back(turn[5]);
				tmp.push_back(turn[3]);
				turn = tmp;
			}
			flag = true;
		}
		else {
			if (curdir == 1)	curdir = 2;
			else if (curdir == 2)	curdir = 1;
			else if (curdir == 3)	curdir = 4;
			else if (curdir == 4) curdir = 3;
		}
	}
}

void dfs(pair<int, int> l,int v) {
	for (int k = 1; k <= 4; k++) {
		int movei = l.first + mv[k].x;
		int movej = l.second + mv[k].y;

		if (movei >= 1 && movei <= n && movej >= 1 && movej <= m) {
			if (visited[movei][movej] == -1 && map[movei][movej] == v) {
				visited[movei][movej] = 1;
				value += 1;
				dfs({ movei,movej }, v);
			}
		}
	}
}

void GetScore() {
	value = 1;
	memset(visited, -1, sizeof(visited));

	visited[loc.first][loc.second] = 1;
	dfs(loc,map[loc.first][loc.second]);

	value = value * map[loc.first][loc.second];
	answer += value;
}

void NextDir() {
	int A = turn[5];
	int B = map[loc.first][loc.second];
	//1:동, 2:서 3:남 4:북
	if (A > B) {
		if (curdir == 1)	curdir = 3;
		else if (curdir == 2)	curdir = 4;
		else if (curdir == 3)	curdir = 2;
		else if (curdir == 4)	curdir = 1;
	}
	else if (A < B) {
		if (curdir == 1)	curdir = 4;
		else if (curdir == 2)	curdir = 3;
		else if (curdir == 3)	curdir = 1;
		else if (curdir == 4)	curdir = 2;
	}
}

int main(void) {
	int testcase;

	cin >> n >> m >> testcase;

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

	loc = make_pair(1, 1);
	turn.push_back(1);
	turn.push_back(4);
	turn.push_back(3);
	turn.push_back(2);
	turn.push_back(5);
	turn.push_back(6);

	for (; testcase > 0; testcase--) {
		MoveDice();
		GetScore();
		NextDir();
	}

	cout << answer << endl;
}

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

원판 돌리기 C++  (0) 2021.10.16
마법사 상어와 파이어스톰 C++  (0) 2021.09.22
상어 중학교 C++  (0) 2021.09.18
원판 돌리기  (0) 2021.04.20
마법사 상어와 파이어스톰  (0) 2021.04.01