나의 작은 valley

[cosPro 1급] 스키장 비용, 마방진 본문

Computer Science/[알고리즘]

[cosPro 1급] 스키장 비용, 마방진

붕옥 아이젠 2023. 8. 13. 13:24
728x90

스키장 비용

정확히 n 일 연속으로 스키장 이용하는데 필요한 최소 비용을 계산하려 합니다. 다음은 스키장에서 판매하는 이용권입니다.

| 이용권 종류 | 스키장을 사용할 수 있는 일수          | 가격            |
|-------------|---------------------------------------|-----------------|
| one_day     | 구매한 날 하루 동안 사용 가능         | one_day_price   |
| multi_day   | 구매한 날부터 multi_day일간 사용 가능 | multi_day_price |

예를 들어 one_day_price = 3, multi_day = 5, multi_day_price = 14라면, 1일 이용권은 3원, 5일 이용권은 14원입니다. n = 6일 때 정확히 6일 연속으로 스키장을 이용하는데 필요한 비용은 다음과 같이 계산합니다.

  • 1일 이용권 x 6장 → 6 x 3원 = 18원
  • 1일 이용권 x 1장 + 5일 이용권 x 1 장 → 1 x 3원 + 1 x 14원 = 17원

따라서 정확히 6일 연속 스키장을 이용하려면 최소 17원이 듭니다. ※ 스키장을 정확히 6일간 이용해야 하므로 5일 이용권을 두 장 살 수는 없습니다.

 

solution 함수의 매개변수로 one_day_price, multi_day, multi_day_price, n가 주어집니다. 이때 정확히 n일 연속 스키장을 이용하는데 필요한 최소 금액을 계산해서 return 하도록 solution 함수를 작성했습니다.

 

그러나, 일부 코드가 잘못되어 코드가 바르게 동작하지 않습니다. 주어진 코드가 모든 입력을 바르게 처리하도록 코드를 수정해주세요. 코드는 _한 줄_만 수정해야 합니다.

 

▣ return값 설명

정확히 n일 연속으로 스키장을 이용하는데 필요한 최소 금액을 return 해주세요.

 

문제 코드)

def solution(one_day_price, multi_day, multi_day_price, n):
    if one_day_price * multi_day <= multi_day_price:
        return n * one_day_price
    else:
        return (n % multi_day) * multi_day_price + (n // multi_day) * one_day_price

 

정답 코드)

def solution(one_day_price, multi_day, multi_day_price, n):
    if one_day_price * multi_day <= multi_day_price:
        return n * one_day_price
    else:
        return (n // multi_day) * multi_day_price + (n % multi_day) * one_day_price
        
one_day_price1 = 3
multi_day1 = 5
multi_day_price1 = 14
n1 = 6
ret1 = solution(one_day_price1, multi_day1, multi_day_price1, n1)
print("solution 함수의 반환 값은", ret1, "입니다.")

one_day_price2 = 2
multi_day2 = 3
multi_day_price2 = 5
n2 = 11
ret2 = solution(one_day_price2, multi_day2, multi_day_price2, n2)
print("solution 함수의 반환 값은", ret2, "입니다.")

처음 if문은 하루 가격 x 멀티 티켓이 지원해주는 기간 이 멀티 티켓 가격보다 싸다면 멀티 티켓을 끊을 이유가 없기에 다 하루 가격 티켓으로 곱한 값을 리턴하는 코드이다.

 

그다음 else문은 적절히 하루 가격 티켓 + 멀티 가격 티켓을 합쳐줘야한다.

가령 14일을 놀러고 5일 티켓이 있다고 하자.

 

그러면 5일 티켓 2장 1일 티켓 4장을 사야한다,

14 = 5 x 2 + 1 x 4

 

2는 14 // 5 몫임을 알 수 있고 4는 14 를 5로 나눈 나머지임을 알 수 있다.  

 

 

 

 

마방진

마방진이란 가로, 세로, 대각선 방향의 수를 더한 값이 모두 같은 정사각형 행렬입니다. 마방진에는 1부터 정사각형 넓이까지, 수가 하나씩 배치되어야 합니다. 아래는 가로, 세로, 대각선 방향의 수를 더한 값이 모두 34인 4 x 4 마방진입니다.

4 x 4 행렬의 두 빈칸을 채워 행렬을 마방진으로 완성하려 합니다. 빈칸은 0으로 표시합니다. 이를 위해 다음과 같이 프로그램 구조를 작성했습니다.

1. 두 빈칸의 위치를 찾습니다.
2. 숫자 1 ~ 16 중 존재하지 않는 숫자 2개를 찾습니다.
3. 첫 번째 빈칸에 작은 숫자를, 두 번째 빈칸에 큰 숫자를 넣어 행렬이 마방진이 되는지 검사합니다.
  4-1. 마방진이라면 [작은 숫자의 행 번호, 작은 숫자의 열 번호, 작은 숫자, 큰 숫자의 행 번호, 큰 숫자의 열 번호, 큰 숫자]를 return 합니다.
  4-2. 마방진이 아니라면 [큰 숫자의 행 번호, 큰 숫자의 열 번호, 큰 숫자, 작은 숫자의 행 번호, 작은 숫자의 열 번호, 작은 숫자]를 return 합니다.

4 x 4 크기 2차원 리스트 matrix가 매개변수로 주어질 때, 이때 빈칸의 위치와 각 칸에 들어갈 수를 담은 리스트를 return 하도록 solution 함수를 작성하려 합니다. 위 구조를 참고하여 코드가 올바르게 동작하도록 빈칸에 주어진 func_a, func_b, func_c 함수와 매개변수를 알맞게 채워주세요.

  • 주어진 행렬은 빈칸을 채우면 반드시 마방진으로 완성할 수 있습니다.

 

▣ return 값 설명

빈칸의 위치와 각 칸에 들어갈 수를 담은 리스트를 return 해주세요.

▣ 예시

| matrix                                           | return        |
|--------------------------------------------------|---------------|
| [[16,2,3,13],[5,11,10,0],[9,7,6,12],[0,14,15,1]] | [4,1,4,2,4,8] |

문제 코드)

def func_a(matrix):
    n = 4
    ret = []
    exist = [False for _ in range(n*n + 1)]
    for i in range(0, n):
        for j in range(0, n):
                exist[matrix[i][j]] = True
    for i in range(1, n*n+1):
        if exist[i] == False:
            ret.append(i)
    return ret

def func_b(matrix):
    n = 4
    ret = []
    for i in range(0, n):
        for j in range(0, n):
            if matrix[i][j] == 0:
                ret.append([i, j])
    return ret

def func_c(matrix):
    n = 4
    goal_sum = sum(range(1, n*n+1))//n
    for i in range(0, n):
        row_sum = 0
        col_sum = 0
        for j in range(0, n):
            row_sum += matrix[i][j]
            col_sum += matrix[j][i]
        if row_sum != goal_sum or col_sum != goal_sum:
            return False

    main_diagonal_sum = 0
    skew_diagonal_sum = 0
    for i in range(0, n):
        main_diagonal_sum += matrix[i][i]
        skew_diagonal_sum += matrix[i][n-1-i]
    if main_diagonal_sum != goal_sum or skew_diagonal_sum != goal_sum:
        return False
    return True

def solution(matrix):
    answer = []
    coords = func_@@@(@@@)
    nums = func_@@@(@@@)

    matrix[coords[0][0]][coords[0][1]] = nums[0]
    matrix[coords[1][0]][coords[1][1]] = nums[1]
    if func_@@@(@@@):
        for i in range(0, 2):
            answer.append(coords[i][0] + 1)
            answer.append(coords[i][1] + 1)
            answer.append(nums[i])
    else:
        matrix[coords[0][0]][coords[0][1]] = nums[1]
        matrix[coords[1][0]][coords[1][1]] = nums[0]
        for i in range(0, 2):
            answer.append(coords[1-i][0] + 1)
            answer.append(coords[1-i][1] + 1)
            answer.append(nums[i])
    return answer

 

정답 코드)

#없는 숫자 찾기 
def func_a(matrix):
    n = 4
    ret = []
    exist = [False for _ in range(n*n + 1)]
    for i in range(0, n):
        for j in range(0, n):
                exist[matrix[i][j]] = True
    for i in range(1, n*n+1):
        if exist[i] == False:
            ret.append(i)
    return ret

#빈칸(값이 0) 찾기
def func_b(matrix):
    n = 4
    ret = []
    for i in range(0, n):
        for j in range(0, n):
            if matrix[i][j] == 0:
                ret.append([i, j])
    return ret

#마방진 검사
def func_c(matrix):
    n = 4
    goal_sum = sum(range(1, n*n+1))//n
    for i in range(0, n):
        row_sum = 0
        col_sum = 0
        for j in range(0, n):
            row_sum += matrix[i][j]
            col_sum += matrix[j][i]
        if row_sum != goal_sum or col_sum != goal_sum:
            return False
    main_diagonal_sum = 0
    skew_diagonal_sum = 0
    for i in range(0, n):
        main_diagonal_sum += matrix[i][i]
        skew_diagonal_sum += matrix[i][n-1-i]
    if main_diagonal_sum != goal_sum or skew_diagonal_sum != goal_sum:
        return False
    return True

def solution(matrix):
    answer = []
    coords = func_b(matrix)
    nums = func_a(matrix)

    matrix[coords[0][0]][coords[0][1]] = nums[0]
    matrix[coords[1][0]][coords[1][1]] = nums[1]
    if func_c(matrix):
        for i in range(0, 2):
            answer.append(coords[i][0] + 1)
            answer.append(coords[i][1] + 1)
            answer.append(nums[i])
    else:
        matrix[coords[0][0]][coords[0][1]] = nums[1]
        matrix[coords[1][0]][coords[1][1]] = nums[0]
        for i in range(0, 2):
            answer.append(coords[1-i][0] + 1)
            answer.append(coords[1-i][1] + 1)
            answer.append(nums[i])
    return answer

#아래는 테스트케이스 출력을 해보기 위한 코드입니다.
matrix = [[16,2,3,13],[5,11,10,0],[9,7,6,12],[0,14,15,1]]
ret = solution(matrix)

#[실행] 버튼을 누르면 출력 값을 볼 수 있습니다.
print("solution 함수의 반환 값은 ", ret, " 입니다.")

matirx를 빈칸이 있는 인덱스 번호를 리스트로 반환하는 func_b에 넣어준다.

 

matrix를 martix에 없는 수들을 리스트로 반환하는 func_a에 넣어준다,

 

빈칸에 순서대로 없는 수들을 넣어준다.

 

matrix가 마방진인지 확인하는 함수에 matrix를 넣어주고 만약에 그 값이 False 즉 마방진이 아니라면

 

빈칸에 순서를 반대로 넣어준다. 이후 해당 값들을 answer에 추가한다.

 

 

그니깐 정답이

a,b 가 아니면 무조건 b,a이라는 특별한 상황이기에 가능한 로직이다.

 

 

 

cf) 마방진 체크 함수가 어떤 매커니즘으로 돌아가는지 참고삼아 봐두는 것도 괜찮을 것 같다.

728x90
Comments