백준 1041번 주사위 C++ 풀이
백준 1041번 주사위 C++ 풀이
1
2
3
4
5
6
7
+---+
| D |
+---+---+---+---+
| E | A | B | F |
+---+---+---+---+
| C |
+---+
- 문제설명
- 주사위는 위와 같이 생기고, 해당 주사위를 N^3개를 가지고 있어 탁자 위에 NxNxN 크기의 정육면체를 만들려고한다.
이 때 5개의 면에 쓰여있는 수의 합의 최솟값을 출력하는 프로그램을 작성하시오
- 주사위는 위와 같이 생기고, 해당 주사위를 N^3개를 가지고 있어 탁자 위에 NxNxN 크기의 정육면체를 만들려고한다.
- 입력예시
1 2
2 // = n 1 2 3 4 5 6 // = A B C D E F
처음 문제를 보았을 때 정육면체에서 보이는 주사위의 종류를 먼저 정리하였다.
- 3개의 면이 보이는 주사위는 8개의 꼭짓점 중 윗면 꼭짓점 4개가 유일하다.
- 2개의 면이 보이는 주사위는 바닥면의 꼭짓점을 포함하여 세로 모서리 4개, 각각 (n-1)개로 4(n-1)개
윗면의 가로 모서리 4개,각각 (n-2)개로 총 4(n-1) + 4*(n-2)개 이다. - 1개의 면이 주사위는 바닥 모서리를 포함하여 4개의 옆면은 (n-1)(n-2), 윗면은 (n-2)(n-2)개로
총 4(n-1)(n-2) + (n-2)*(n-2)개 이다.
정육면체 총합
1
(주사위 3개의 면 합 * 4) + 주사위 2개의 면 합 * 4 * (2n-3) + 주사위 1개의 면 합*(4(n-1)(n-2) + (n-2)(n-2))
위의 식으로 표현할 수 있으며 해당 값이 최소 값이 될려면 주사위의 3개의 면, 2개의 면, 1개의 면 각각 최솟값을 찾으면 된다고 생각했다.
1개 면의 최소값을 구하는 것은 단순하였는데 2개,3개에 대한 최소값을 구하는데 있어서 인접하는 2개 또는 3개의 면에 대한 합이라는 조건에 대해서 해결하려는 방법을 찾는데 시간이 걸린 것 같았다.
결국 위의 주사위를 보면 각각 마주 보는 주사위 면이 3 쌍이 존재하는 것을 발견하여 (A,F) , (B,E) , (C,D) 중에 작은 값들을 선택하면 무조건 인접한 면이라는 것을 알 수 있었다.
저 3쌍의 최소 값을 통해서 합을 구해 계산하면 쉽게 구할 수 있고 값의 범위를 고려하지 않아서 예제에 대한 정답이 틀리게 나와 많이 헤맸었다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <algorithm>
using namespace std;
int dice[6];
// (0,5) , (1,4) (2,3)
// (A,F) , (B,E) , (C,D)
int main(){
int maxVal = 0;
long long n;
long long answer = 0;
cin >> n;
for(int i = 0; i < 6; i++){
cin >> dice[i];
answer += dice[i];
maxVal = max(maxVal,dice[i]);
}
if(n == 1){
answer -= maxVal;
}else{
answer = 0;
int minValue[3];
minValue[0] = min(dice[0],dice[5]);
minValue[1] = min(dice[1],dice[4]);
minValue[2] = min(dice[2],dice[3]);
sort(minValue, minValue+3);
int sum1 = minValue[0];
int sum2 = sum1 + minValue[1];
int sum3 = sum2 + minValue[2];
//8개 꼭짓점 중 4개는 3면 4개는 2면
//2개의 면 보이는 세로 4 (n-1)개 , 윗면 가로 4개는 (n-2)개
//옆면 4개는 (n-1)*(n-2), 윗면 1개는 (n-2)*(n-2);
answer += sum3 * 4;
answer += sum2 * 4 * (2*n - 3);
answer += sum1 * (4*(n-1)*(n-2) + (n-2)*(n-2));
}
cout << answer << "\n";
return 0;
}
This post is licensed under CC BY 4.0 by the author.