[ 백준 ] 2116 / 주사위 쌓기
# Appreciation
/*
* Problem :: 2116 / 주사위 쌓기
*
* Kind :: Brute Force + Simulation
*
* Insight
* - 서로 붙어 있는 두 개의 주사위에서
* 아래에 있는 주사위 윗면에 적혀있는 숫자는
* 위에 있는 주사위 아랫면에 적혀있는 숫자와 같아야 한다
* + 주사위에서 마주보고 있는 값들을 알고 있어야 한다
* 마주보고 있는 값들을 알기 위해서는 각 값들이 위치한 주사위의 면을 알아야 한다
* # 주사위의 면을 알면 주사위의 값을 알 수 있어야 한다 / index -> val
* 주사위의 값을 알면 주사위의 면을 알 수 있어야 한다 / val -> index
* -> n번 주사위마다 위의 정보 알아내 저장하자!
*
* - D = 주사위의 정보가 담긴 구조체 배열
* D[i] = (i-1)번 주사위의 정보가 담긴 구조체
* D[i].i2v = (i-1)번 주사위의 index -> val 정보
* D[i].v2i = (i-1)번 주사위의 val -> index 정보
* O[j] = j 면을 마주보는 면
* + 현재 i번 주사위까지 쌓였고
* up_val = 맨 위에 쌓인 주사위의 윗면의 값이라면
* # down_idx = 다음에 쌓일 주사위의 아랫면
* = D[i].v2i[up_val]
* up_val = 다음에 쌓일 주사위의 윗면
* = D[i].i2v[O[down_idx]]
*
* Point
* - 마주보는 면들은 다음과 같다
* (A,F) (B,D) (C,E)
* + A=0, B=1, ..., F=5 라고 생각하면 다음과 같다
* (0,5) (1,3) (2,4)
*/
# Code
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;
#define endl '\n'
// Set up : Global Variables
enum Face { A, B, C, D, E, F }; /* 주사위의 면 */
struct Dice { int v2i[6+1], i2v[6]; };
int O[6] = { F, D, E, B, C, A }; /* 마주보는 면 */
// Set up : Functions Declaration
/* None */
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int N; cin >> N;
Dice D[N];
for (int i=0; i<N; i++) {
for (int j=0; j<6; j++) {
int v; cin >> v;
D[i].v2i[v] = j; /* val -> index */
D[i].i2v[j] = v; /* index -> val */
}
}
// Process
/* 주사위의 옆면들에 적힌 값들 중 최댓값을 반환하는 함수 */
function<int(int[6],int)> getSideMaxVal = [](int i2v[6], int down_idx){
int mx = -1;
for (int i=0; i<6; i++) {
if (not(i == down_idx || i == O[down_idx])) {
mx = max(mx, i2v[i]);
}
} return mx;
};
int ans = -1;
for (int i=0; i<6; i++) {
int down_idx = i; /* 현재 아랫면 */
int tmp = getSideMaxVal(D[0].i2v, down_idx); /* 현재 옆면의 숫자의 합의 최댓값 */
int up_val = D[0].i2v[O[down_idx]]; /* 현재 윗면의 값 */
for (int j=1; j<N; j++) {
down_idx = D[j].v2i[up_val];
tmp += getSideMaxVal(D[j].i2v, down_idx);
up_val = D[j].i2v[O[down_idx]];
} ans = max(ans, tmp);
}
// Control : Output
cout << ans << endl;
}
// Helper Functions
/* None */
Author And Source
이 문제에 관하여([ 백준 ] 2116 / 주사위 쌓기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@gglifer/백준-2116-주사위-쌓기
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
/*
* Problem :: 2116 / 주사위 쌓기
*
* Kind :: Brute Force + Simulation
*
* Insight
* - 서로 붙어 있는 두 개의 주사위에서
* 아래에 있는 주사위 윗면에 적혀있는 숫자는
* 위에 있는 주사위 아랫면에 적혀있는 숫자와 같아야 한다
* + 주사위에서 마주보고 있는 값들을 알고 있어야 한다
* 마주보고 있는 값들을 알기 위해서는 각 값들이 위치한 주사위의 면을 알아야 한다
* # 주사위의 면을 알면 주사위의 값을 알 수 있어야 한다 / index -> val
* 주사위의 값을 알면 주사위의 면을 알 수 있어야 한다 / val -> index
* -> n번 주사위마다 위의 정보 알아내 저장하자!
*
* - D = 주사위의 정보가 담긴 구조체 배열
* D[i] = (i-1)번 주사위의 정보가 담긴 구조체
* D[i].i2v = (i-1)번 주사위의 index -> val 정보
* D[i].v2i = (i-1)번 주사위의 val -> index 정보
* O[j] = j 면을 마주보는 면
* + 현재 i번 주사위까지 쌓였고
* up_val = 맨 위에 쌓인 주사위의 윗면의 값이라면
* # down_idx = 다음에 쌓일 주사위의 아랫면
* = D[i].v2i[up_val]
* up_val = 다음에 쌓일 주사위의 윗면
* = D[i].i2v[O[down_idx]]
*
* Point
* - 마주보는 면들은 다음과 같다
* (A,F) (B,D) (C,E)
* + A=0, B=1, ..., F=5 라고 생각하면 다음과 같다
* (0,5) (1,3) (2,4)
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;
#define endl '\n'
// Set up : Global Variables
enum Face { A, B, C, D, E, F }; /* 주사위의 면 */
struct Dice { int v2i[6+1], i2v[6]; };
int O[6] = { F, D, E, B, C, A }; /* 마주보는 면 */
// Set up : Functions Declaration
/* None */
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int N; cin >> N;
Dice D[N];
for (int i=0; i<N; i++) {
for (int j=0; j<6; j++) {
int v; cin >> v;
D[i].v2i[v] = j; /* val -> index */
D[i].i2v[j] = v; /* index -> val */
}
}
// Process
/* 주사위의 옆면들에 적힌 값들 중 최댓값을 반환하는 함수 */
function<int(int[6],int)> getSideMaxVal = [](int i2v[6], int down_idx){
int mx = -1;
for (int i=0; i<6; i++) {
if (not(i == down_idx || i == O[down_idx])) {
mx = max(mx, i2v[i]);
}
} return mx;
};
int ans = -1;
for (int i=0; i<6; i++) {
int down_idx = i; /* 현재 아랫면 */
int tmp = getSideMaxVal(D[0].i2v, down_idx); /* 현재 옆면의 숫자의 합의 최댓값 */
int up_val = D[0].i2v[O[down_idx]]; /* 현재 윗면의 값 */
for (int j=1; j<N; j++) {
down_idx = D[j].v2i[up_val];
tmp += getSideMaxVal(D[j].i2v, down_idx);
up_val = D[j].i2v[O[down_idx]];
} ans = max(ans, tmp);
}
// Control : Output
cout << ans << endl;
}
// Helper Functions
/* None */
Author And Source
이 문제에 관하여([ 백준 ] 2116 / 주사위 쌓기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@gglifer/백준-2116-주사위-쌓기저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)