티스토리 뷰

PS

백준 1041. 주사위

tose33 2021. 8. 11. 17:00

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

 

1041번: 주사위

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

www.acmicpc.net

 

생각해보면 주사위들을 3가지 케이스로 나눌수 있다.

1. 한면만 보이는 주사위

2. 두면이 보이는 주사위

3. 세면이 보이는 주사위 

 

그렇다면 정육면체의 한 변이 n일 때, 각각의 케이스의 주사위가 몇개인지 구한후에 

한면만 보이는 주사위는 주사위의 6개의 숫자중 최솟값,

두면이 보이는 주사위는 인접한 두 숫자의 합중 최솟값,

세면이 보이는 주사위는 인접한 세 숫자의 합중 최솟값,

을 구한후 각각의 갯수에 곱해준후 모두 합하면 답이다.

 

 

여기까지는 금방 생각했는데 세면이 보이는 주사위의 인접한 세 숫자의 합중 최솟값을 구하는데 애를 먹었다.

결국 이부분은 다른분들의 코드를 찾아봤는데 아주 간단한 방법이 있었다.

인접한 세 숫자의 합중 최솟값을 구하는 방법은 각 마주보는 세쌍의 숫자중 작은값을 더한값이다.

 

저번에 주사위쌓기 문제도 그렇고 도형에 약한것 같다

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

long long n;
long long dice[6];

// 최소가 되는 인접한 두면의합 찾음
long long FindMinTwoSide()
{
    long long minSum = 99999;
    int idx[6] = {5,4,3,2,1,0};
    for(int i = 0; i < 6; i++)
    {
        for(int j = 0; j < 6; j++)
        {
            // 같은면, 반대면 계산 안함
            // 반대면은 인접하지 못하므로
            if(j == i || j == idx[i]) continue;
            long long sum = dice[i] + dice[j];

            minSum = min(sum ,minSum);
        }
    }
    return minSum;
}

// 최소가 되는 인접한 세면의합 찾음
long long FindMinThreeSide()
{
    int idx[4] = {0,1,5,4};
    int idx2[4] = {1,5,4,0};

    long long sum = dice[0] + dice[1] + dice[2];

    for(int i = 0; i < 4; i++)
    {
        if(dice[idx[i]] + dice[idx2[i]] + dice[3] > dice[idx[i]] + dice[idx2[i]] + dice[2])
            sum = min(sum, dice[idx[i]] + dice[idx2[i]] + dice[2]);
        else
            sum = min(sum, dice[idx[i]] + dice[idx2[i]] + dice[3]);
    }
    return sum;
}

// 마주 보는 세쌍의 면중 작은값을 더한값 ]
long long FindMinThreeSide2()
{
    int a1 = min(dice[0], dice[5]);
    int a2 = min(dice[1], dice[4]);
    int a3 = min(dice[2], dice[3]);
    return a1+a2+a3;
}

int main()
{
    cin >> n;
    long long min_num = 55;
    for(int i = 0; i < 6; i++)
    {
        cin >> dice[i];
        min_num = min(min_num, dice[i]);
    }

    // n=1일 경우 예외
    if(n == 1)
    {
        sort(dice, dice+6);
        int sum = 0;
        for(int i = 0; i < 5; i++)
        {
            sum += dice[i];
        }
        cout << sum;
        return 0;
    }

    // 한 면이 보이는 주사위
    long long oneSideNum = (n-2)*(n-2)+(n-2)*(n-1)*4;
    long long oneSide = oneSideNum * min_num;

    // 두 면이 보이는 주사위
    long long twoSideNum = (n-1) * 4 + (n-2) * 4;
    long long twoSide = twoSideNum * FindMinTwoSide();

    // 세 면이 보이는 주사위
    long long threeSideNum = 4;
    long long threeSide = threeSideNum * FindMinThreeSide2();

    long long ans = oneSide + twoSide + threeSide;

    cout << ans;

}

 

'PS' 카테고리의 다른 글

백준 9237. 이장님 초대  (0) 2021.08.13
백준 1343. 폴리오미노  (0) 2021.08.12
백준 11497. 통나무 건너뛰기  (0) 2021.08.11
백준 15903. 카드 합체 놀이  (0) 2021.08.11
백준 16953. A->B  (0) 2021.08.10
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
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
글 보관함