개발/백준

[백준] 2116번. 주사위 쌓기 (C++)

yun000 2024. 11. 21. 15:26

문제

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

풀이

Front Back

다이스가 ABCDEF이다. 여기서

A가 bottom 이면 F가 top이다 / F가 bottom이면 A가 top이다

B가 bottom 이면 D가 top이다 / D가 bottom이면 B가 top이다

C가 bottom 이면 E가 top이다 / E가 bottom이면 C가 top이다

알파벳들을 각각 숫자로 나타내면

0  5 / 5  0

1  3 / 3  1

2  4 / 4  2

이다.

이 관계를 map<int,int>bottomTop으로 저장한 것이다.

 

Check

1번 다이스를 두는 방식에 따라 나머지 다이스들이 다 정해진다.

그래서 1번 다이스의 밑면이 1~6일 때의 상황을 하나씩 살펴보면 된다

 

diceCheck 재귀함수

이전 다이스의 top값을 알면

현재 확인하는 다이스의 bottom, top을 알 수 있다.

 

확인 후 bottom, top을 제외한 모든 숫자들 중에서 가장 큰 값을 sum에 더해주면 된다.

어차피 옆면은 회전이 가능하기 때문이다

 

이것을 N번 반복하자.

 

코드

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;

int N;
int answer;
int sum;
map<int, int>bottomTop;
vector<vector<int>> dice;

void diceCheck(int prevTop, int diceCount)
{
	if (diceCount >= N) { return; }

	int bottom = prevTop;
	int bottomIndex = 
		find(dice[diceCount].begin(), dice[diceCount].end(),
		prevTop) - dice[diceCount].begin();
	
	int topIndex = bottomTop[bottomIndex];
	int top = dice[diceCount][topIndex];

	//bottom, top이 아닌 것 중에 최대값 찾음
	int max = 0;
	for (int i = 1; i <= 6; i++)
	{
		if (i == bottom || i == top)continue;
		if (max < i) { max = i; }
	}
	sum += max;

	diceCheck(top, diceCount + 1);
}

int main()
{
	//INPUT
	cin >> N;
	dice= vector<vector<int>>(N);
	for (int i = 0; i < N; i++) 
	{
		int num;
		for (int k = 0; k < 6; k++)
		{
			cin >> num; dice[i].push_back(num);
		}
	}

	//Bottom Top
	bottomTop[0] = 5;
	bottomTop[5] = 0;
	bottomTop[1] = 3;
	bottomTop[3] = 1;
	bottomTop[2] = 4;
	bottomTop[4] = 2;

	//CHECK
	for (int i = 1; i <=6; i++)
	{
		sum = 0;
		diceCheck(i, 0);
		if (sum > answer) { answer = sum; }
	}
	
	//RESULT
	cout << answer;
}