https://www.acmicpc.net/problem/2116
브루트포스, 구현 문제다.
주사위는 아래와 같이 생겼고, A B C D E F 순으로 입력이 들어온다.
이 때 A - F, B - D, C - E 가 마주본다.
int pairs[6] = { 5, 3, 4, 1, 2, 0 }; 와 같이 맞은 편 짝에 대한 배열을 만들었다.
이 문제는 주사위를 쌓을 때 윗면의 숫자와 윗 층 주사위의 아랫면 숫자가 같아야 한다.
따라서 맨 아래 주사위의 방향만 결정하면 그 위 주사위들은 위아래는 고정한 채 옆으로만 돌릴 수 있다.
즉, 옆 면들 중 최댓값을 찾으면 된다.
옆 면들 중 최댓값을 찾는 방법에 대해 여러 방법을 생각했다.
1. 위아래 면을 찾고 나머지 값들에 대해 max 하기.
=> 이 방법은 아랫면을 찾아야 윗 면을 찾을 수 있기 때문에 반복문 한 번으로 불가능하다.
가능하나 반복문 한 번에 해결하고 싶었다.
2. 두 면을 제외하는 것이기 때문에 가장 작은 최댓값은 4다.
=> 아랫면 값을 찾으면 바로 윗면 값을 찾을 수 있고, 이 두 값을 알면 옆면 들 중 최댓값을 쉽게 찾을 수 있다.
tmp 변수 선언 시 6으로 초기화하고, 윗면이나 아랫면이 6이라면 5, 윗면 + 아랫면이 11이라면 4가 최댓값이다.
첫 주사위를 놓는 방향을 고려해 위 과정을 6번 반복한 후 그 중 최댓값이 정답이다.
#include <iostream>
using namespace std;
int n;
int arr[10000][6];
int pairs[6] = { 5, 3, 4, 1, 2, 0 };
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < 6; j++) {
cin >> arr[i][j];
}
}
int result = 0;
for (int i = 0; i < 6; i++) {
int res = 6;
int top = arr[0][pairs[i]];
int bottom = arr[0][i];
if (top == 6 || bottom == 6) res = 5;
if (bottom + top == 11) res = 4;
for (int j = 1; j < n; j++) {
bottom = top;
for (int k = 0; k < 6; k++) {
if (top == arr[j][k]) {
top = arr[j][pairs[k]];
break;
}
}
int tmp = 6;
if (top == 6 || bottom == 6) tmp = 5;
if (bottom + top == 11) tmp = 4;
res += tmp;
}
result = max(result, res);
}
cout << result;
}