Post

백준 1041번, 주사위

백준 1041번 c++ 문제풀이


문제:

1
2
3
4
5
6
7
    +---+        
    | D |        
+---+---+---+---+
| E | A | B | F |
+---+---+---+---+
    | C |        
    +---+  

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

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

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

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

풀이:

N^3의 주사위를 가지고 NNN의 정육면체를 만들었다고 보자.

  1. 세 면이 보이는 주사위의 개수, 두 면이 보이는 주사위의 개수, 한 면이 보이는 주사위의 각각의 개수를 구한다.
  2. 최솟값이므로 A, B, C, D, E, F 중에서 가장 작은 수를 가진 면을 찾는다.
  3. 한 면만 보이는 주사위는 가장 작은 면 하나만 고른다.
  4. 두 면이 보이는 주사위는 가장 작은 면 하나를 고르고 -> 그 면과 마주보고 있는 면을 제외한 나머지의 면에서 가장 작은 면을 고른다.
  5. 세 면이 보이는 주사위는 가장 작은면 하나를 고르고 -> 그 면과 마주보고 있는 면을 제외한 나머지의 면에서 가장 작은 면(만약 A면이 가장 작은 값이라면 F면을 제외한 나머지 면중 가장 작은 값)을 고른 후 -> 처음에 제외한 면과 방금 단계에서 고른면과 마주보는 면을 제외한 나머지 두면에서 가장 작은 값을 고른다.

세 면이 보이는 주사위는 항상 4개이다.
두 면이 보이는 주사위는 4(N-2) + 4(N-1) = 8N-12 개이다.
한 면이 보이는 주사위는 (N-2)(N-2) + (N-2)(N-1)*4 = 5N^2-16N+12 개이다.

코드:

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
#include <math.h>
using namespace std;

int main(){
int n;
long long n1 = 0;
long long n2 = 0;
long long n3 = 0;
int input[6];
int minn = 100;
int minn1 = 100;
int minn2 = 100;
int max = 0;
int dice;
int dice1;
long long result = 0;
//0 5
//1 4
//2 3

cin >> n;

n1 = 5*pow(n,2) - 16*n + 12;
n2 = 8*n -12;
n3 = 4;

for(int i=0;i<6;i++){
    cin >> input[i];
}
if(n==1){
    for(int i=0;i<6;i++){
    if(max <= input[i]){
        max = input[i];
    }
    }
    for(int i=0;i<6;i++){
    result+=input[i];
    }

    result = result - max;
    cout << result;
    return 0; 
}else{
    for(int j=0;j<6;j++){
        if(minn > input[j]){
        minn = input[j];
        dice = j;
        }
    }

    for(int i=0;i<6;i++){
        if(dice == i){//첫번째에 골랐던 배열은 제외하고 최솟값을 구한다.
        continue;
        }
        else if(i + dice == 5){ //마주보는 면의 배열 순서의 합이 5이다. 
        continue;
        }
        else if(minn1 > input[i]){
        minn1 = input[i];
        dice1 = i;
        }
    }

    for(int i=0;i<6;i++){
        if(dice == i || dice1 == i){
        continue;
        }
        if(i + dice == 5){
        continue;
        }
        else if(i + dice1 == 5){
        continue;
        }
        else if(minn2 > input[i]){
        minn2 = input[i];
        }
    }
    
    result = n1*minn + n2*(minn+minn1)+ n3*(minn+minn1+minn2);
    }
    
    
cout << result;
return 0;
}

아주 더럽게 코드를 짠거 같지만 그래도 코드는 맞았다. 담에는 더 깔끔하게 짜도록 노력해봐야겠다.

This post is licensed under CC BY 4.0 by the author.