문제 정보
- 문제 링크
- 제출 언어: Swift
- 알고리즘 분류:
- 구현
문제 설명
카카오톡에서는 이모티콘을 무제한으로 사용할 수 있는 이모티콘 플러스 서비스 가입자 수를 늘리려고 합니다.
이를 위해 카카오톡에서는 이모티콘 할인 행사를 하는데, 목표는 다음과 같습니다.
- 이모티콘 플러스 서비스 가입자를 최대한 늘리는 것.
- 이모티콘 판매액을 최대한 늘리는 것.
1번 목표가 우선이며, 2번 목표가 그 다음입니다.
이모티콘 할인 행사는 다음과 같은 방식으로 진행됩니다.
- n명의 카카오톡 사용자들에게 이모티콘 m개를 할인하여 판매합니다.
- 이모티콘마다 할인율은 다를 수 있으며, 할인율은 10%, 20%, 30%, 40% 중 하나로 설정됩니다.
카카오톡 사용자들은 다음과 같은 기준을 따라 이모티콘을 사거나, 이모티콘 플러스 서비스에 가입합니다.
- 각 사용자들은 자신의 기준에 따라 일정 비율 이상 할인하는 이모티콘을 모두 구매합니다.
- 각 사용자들은 자신의 기준에 따라 이모티콘 구매 비용의 합이 일정 가격 이상이 된다면, 이모티콘 구매를 모두 취소하고 이모티콘 플러스 서비스에 가입합니다.
다음은 2명의 카카오톡 사용자와 2개의 이모티콘이 있을때의 예시입니다.
사용자비율가격
1 | 40 | 10,000 |
2 | 25 | 10,000 |
이모티콘가격
1 | 7,000 |
2 | 9,000 |
1번 사용자는 40%이상 할인하는 이모티콘을 모두 구매하고, 이모티콘 구매 비용이 10,000원 이상이 되면 이모티콘 구매를 모두 취소하고 이모티콘 플러스 서비스에 가입합니다.
2번 사용자는 25%이상 할인하는 이모티콘을 모두 구매하고, 이모티콘 구매 비용이 10,000원 이상이 되면 이모티콘 구매를 모두 취소하고 이모티콘 플러스 서비스에 가입합니다.
1번 이모티콘의 가격은 7,000원, 2번 이모티콘의 가격은 9,000원입니다.
만약, 2개의 이모티콘을 모두 40%씩 할인한다면, 1번 사용자와 2번 사용자 모두 1,2번 이모티콘을 구매하게 되고, 결과는 다음과 같습니다
문제 풀이
이 문제는 단순 구현 풀이로 풀 수 있었다.
1) 이모티콘 할인율 조합하기
2) 각 할인율 조합마다 고객들이 할인율 적용한 가격 계산해서 이모티콘 플러스 가입자인지, 총 매출을 높인 것인지 정하기
3) 이모티콘 플러스 가입자 -> 총 매출액 이 우선순위로 가장 높은 값을 갱신해주기
이렇게 3개의 기능을 구현하는 것이 이 문제의 핵심 포인트였다.
1) 이모티콘 할인율 조합하기
이모티콘마다 각자 다른 할인율을 가지게 하기 위해 이모티콘 할인율을 조합하는 방법은 재귀함수를 사용하였다.
'var candidateRates: [[Int]] = []' 이 2차원 배열을 생성하여 할인율을 조합하는 후보들을 다 담아주었다.
할인율은 10,20,30,40 이렇게 4가지이고, 총 이모티콘 개수을 n개라고 하면 중복을 허락하기 때문에 4^n의 후보들이 나올 것이다.
for문으로 할인율 4개에 해당하는 값들을 넣어주었고 할인율 조합이 이모티콘 개수와 같아졌을 때 candidateRates에 후보를 append해주고 재귀를 종료시켰다.
let discountRate = [10, 20, 30, 40]
var candidateRates: [[Int]] = []
// 이모티콘의 할인율 조합이 되는 경우의 수 모두 candidateRates 배열에 넣기
func makeCases(_ arr: [Int]) {
if arr.count == emoticons.count {
candidateRates.append(arr)
return
}
for i in 0..<4 {
var tempArr = arr
tempArr.append(discountRate[i])
makeCases(tempArr)
}
}
2. 각 할인율 후보들마다 이모티콘 플러스 가입자수 & 총 매출 계산하기
이중 for문을 돌면서 각 할인율 후보들의 각 유저들의 이모티콘 플러스 가입여부를 계산해준다
유저가 원하는 할인율의 이모티콘의 할인가들을 다 더해서,
- 유저의 일정 금액을 넘을 경우 이모티콘 플러스 가입자의 수 += 1
- 넘지 않을 경우 각 할인율의 총 매출에 해당 금액을 더해준다.
// 각 할인율 후보들마다 이모티콘 플러스 가입자수와 전체 매출을 계산하고 최댓값을 갱신해준다
for candidateRate in candidateRates {
var plusServiceUsers = 0
var totalSales = 0
for user in users {
var tempSales = 0
for idx in 0..<candidateRate.count {
if candidateRate[idx] >= user[0] {
tempSales += emoticons[idx] - (emoticons[idx] * candidateRate[idx] / 100)
}
}
if tempSales >= user[1] {
plusServiceUsers += 1
} else {
totalSales += tempSales
}
}
3) 최대 결과값 구하기
문제에서 조건을 주어진 우선순위에 따라 결과값을 구하면 마무리이다.
'var result: [Int] = [0, 0]'를 초기값으로 두고
- result[0] 값보다 현재 할인율 조합의 이모티콘 플러스 가입자수가 많을 경우
- result[0] 값과 이모티콘 플러스 가입자수가 같으면서 result[1] 값보다 현재 할인율 조합의 총 매출액이 높은 경우
위의 경우에 result값을 갱신해주었다.
전체 코드
import Foundation
func solution(_ users:[[Int]], _ emoticons:[Int]) -> [Int] {
let discountRate = [10, 20, 30, 40]
var candidateRates: [[Int]] = []
var result: [Int] = [0, 0]
// 이모티콘의 할인율 조합이 되는 경우의 수 모두 candidateRates 배열에 넣기
func makeCases(_ arr: [Int]) {
if arr.count == emoticons.count {
candidateRates.append(arr)
return
}
for i in 0..<4 {
var tempArr = arr
tempArr.append(discountRate[i])
makeCases(tempArr)
}
}
makeCases([])
// 각 할인율 후보들마다 이모티콘 플러스 가입자수와 전체 매출을 계산하고 최댓값을 갱신해준다
for candidateRate in candidateRates {
var plusServiceUsers = 0
var totalSales = 0
for user in users {
var tempSales = 0
for idx in 0..<candidateRate.count {
if candidateRate[idx] >= user[0] {
tempSales += emoticons[idx] - (emoticons[idx] * candidateRate[idx] / 100)
}
}
if tempSales >= user[1] {
plusServiceUsers += 1
} else {
totalSales += tempSales
}
}
// 1순위: 이모티콘 플러스 가입자수, 2순위: 전체 매출
if result[0] == plusServiceUsers {
if result[1] < totalSales {
result = [plusServiceUsers, totalSales]
}
} else if result[0] < plusServiceUsers {
result = [plusServiceUsers, totalSales]
}
}
return result
}
'Algorithm > 문제풀이' 카테고리의 다른 글
[백준/Swift] 17140 이차원 배열과 연산 (0) | 2023.06.13 |
---|---|
[백준/Swift] 16953 A -> B (0) | 2023.06.06 |
[백준/Swift] 2606 바이러스 (0) | 2023.06.06 |
[프로그래머스/Swift] 택배 배달과 수거하기 (0) | 2023.06.05 |
[백준/Swift] 1303 전쟁 - 전투 (1) | 2023.06.03 |