코딩/백준

[백준]1041번 주사위 - C/C++

최선을 다하는 2022. 1. 19. 12:40

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

 

1041번: 주사위

첫째 줄에 N이 주어진다. 둘째 줄에 주사위에 쓰여 있는 수가 주어진다. 위의 그림에서 A, B, C, D, E, F에 쓰여 있는 수가 차례대로 주어진다. N은 1,000,000보다 작거나 같은 자연수이고, 쓰여 있는 수

www.acmicpc.net

문제

    +---+        
    | D |        
+---+---+---+---+
| E | A | B | F |
+---+---+---+---+
    | C |        
    +---+        

주사위는 위와 같이 생겼다. 주사위의 여섯 면에는 수가 쓰여 있다. 위의 전개도를 수가 밖으로 나오게 접는다.

A, B, C, D, E, F에 쓰여 있는 수가 주어진다.

지민이는 현재 동일한 주사위를 N3개 가지고 있다. 이 주사위를 적절히 회전시키고 쌓아서, N×N×N크기의 정육면체를 만들려고 한다. 이 정육면체는 탁자 위에 있으므로, 5개의 면만 보인다.

N과 주사위에 쓰여 있는 수가 주어질 때, 보이는 5개의 면에 쓰여 있는 수의 합의 최솟값을 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 N이 주어진다. 둘째 줄에 주사위에 쓰여 있는 수가 주어진다. 위의 그림에서 A, B, C, D, E, F에 쓰여 있는 수가 차례대로 주어진다. N은 1,000,000보다 작거나 같은 자연수이고, 쓰여 있는 수는 50보다 작거나 같은 자연수이다.

출력

첫째 줄에 문제의 정답을 출력한다.


N이 1일때는 주사위 하나를 올려놓는 것이므로 가장 큰 숫자를 보이지 않게 탁자 위에 올려놓으면 된다.

N이 2 이상일때는 위 그림과 같은 규칙으로 보이는 면들의 최솟값이 결정되게 된다. 이제 보이는 면의 숫자를 결정해야 하는데 세 숫자가 붙어있어야 3면을 보이게 주사위를 배치를 할 수 있다는 점을 주의하자. 문제의 그림의 전개도를 보면 A와 F 중 작은 숫자 1개 B와 E 중 최솟값 1개 그리고 C와 D 중 최솟값 1개를 설정하여 나온 숫자들을 작은 순서대로 1번 2번 3번이라 할 때 모든 숫자의 합은

   1면이 보이는 것 * (1번)

+ 2면이 보이는 것 * (1번 + 2번)

+ 3면이 보이는 것 * (1번 + 2번 + 3번) 으로 더했을 때 최솟값이 된다.

 

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

int arr[6] ;
int cube[3];
long long n;
long long ans = 0;

void solve() {
	cube[0] = min(arr[0], arr[5]);
	if (n == 1) {
		sort(arr, arr + 6);
		ans = arr[0] + arr[1] + arr[2] + arr[3] + arr[4];
	}
	else {
		cube[1] = min(arr[2], arr[3]);
		cube[2] = min(arr[1], arr[4]);
		sort(cube,cube+3);
		ans += cube[0] * (5 * n * n - 8 * n + 4);
		ans += cube[1] * (8 * n - 8);
		ans += 4 * cube[2];
	}
	cout << ans;
}

int main() {
	cin >> n;
	for (int i = 0; i < 6; i++) {
		int t;
		cin >> t;
		arr[i] = t;
	}
	solve();
	return 0;
}

이 문제를 풀기 시작하고 대부분의 시간은 그림을 그리며 생각했던 것 같다. 저 식들을 구하는데 꽤 애를 먹고 숫자를 대입해보니 내가 맞게 푼 것 같았다. 하지만 선택되는 면 3개를 선정하는 것을 처음에는 A와 F 중 1개 BCDE 중 작은 것 2개로 설정했는데 생각해보니 맞은편에 있는 두 개는 설정할 수가 없었다. 그래서 옆면 12 23 34 41을 비교해야 하나 하고 있었는데 깔끔하게 비교하는 방법이 떠오르지 않아 또 애를 먹었다. 그러다가 결국 붙어있는 면의 최소를 구하려면 맞은편에 있는 숫자들 중 작은 것들만 고른다면 알아서 인접해있다는 사실을 알았다. 여기까지 했는 데도 틀렸습니다가 떴다. 다시 보니 옆면을 처음에 잘 못 구했을 때 A와 F 중 한 개는 포함이라는 생각에 N=1 일 때도 A와 F 중 한 개를 무조건 포함시켰는데 그러면 안됐다. 

결국 사소한 실수들이 쌓여 여러번의 틀렸습니다를 낳은 것 같다. 그래도 이제는 블록 문제들이 나오면 좀 더 친숙하게 접근할 수 있을 것 같다!