문제 개요
슈퍼마켓에서 세일 행사를 진행한다고 가정해 보겠습니다. 이 행사에서는 매 n번째 고객에게 결제 금액에 대한 할인이 적용됩니다. 슈퍼마켓에는 여러 상품이 있으며, i번째 상품의 ID는 products[i], 해당 상품의 단위당 가격은 prices[i]입니다.
시스템은 도착한 고객 수를 계속 집계하다가, n번째 고객이 도착하면 그 고객의 청구서에 할인을 적용합니다. 할인이 적용된 후에는 다시 고객 수를 처음부터 집계합니다. 고객은 각 상품을 원하는 수량만큼 주문할 수 있으며, product[i]는 고객이 주문한 i번째 상품의 ID, amount[i]는 해당 상품의 주문 수량을 의미합니다.
우리는 바로 이 시스템을 구현해야 합니다. Cashier 클래스는 다음과 같은 메서드를 가져야 합니다.
Cashier 클래스의 메서드
Cashier(int n, int discount, int[] products, int[] prices)— 생성자로, 고객 수 n, 할인율, 상품 목록 및 각 상품의 가격으로 객체를 초기화합니다.double getBill(int[] product, int[] amount)— 청구 금액을 반환하며, 필요한 경우 할인을 적용합니다. 실제 값과 10-5 이내의 오차는 정답으로 인정됩니다.
예시
Cashier(3, 50, [1,2,3,4,5,6,7], [100,200,300,400,300,200,100])로 객체를 초기화한 뒤, 아래와 같이 getBill 메서드를 순서대로 호출해 보겠습니다.
getBill([1,2],[1,2]), getBill([3,7],[10,10]), getBill([1,2,3,4,5,6,7],[1,1,1,1,1,1,1]), getBill([4],[10]), getBill([7,3],[10,10]), getBill([7,5,3,1,6,4,2],[10,10,10,9,9,9,7]), getBill([2,3,5],[5,3,2])
이때 출력 결과는 다음과 같습니다.
[500.0, 4000.0, 800.0, 4000.0, 4000.0, 7350.0, 2500.0]
풀이 접근 방법
이 문제는 다음 단계를 따라 해결할 수 있습니다.
상품 ID와 가격을 저장할 맵
order를 정의합니다.생성자(Cashier)는 다음과 같이 동작합니다.
고객 카운터
curr을 0으로 초기화합니다.0부터 가격 배열의 크기까지 반복하면서
order[products[i]] = prices[i]형태로 상품별 가격을 저장합니다.n과 할인율(discount)을 멤버 변수에 저장합니다.
getBill 메서드는 다음과 같이 동작합니다.
curr을 1 증가시키고,curr == n이면flag = true, 그렇지 않으면false로 설정합니다.curr == n이라면curr을 0으로 되돌려 다시 고객 수를 집계합니다.총액
ret을 0으로 초기화합니다.주문 상품 배열을 순회하면서 각 상품의 단가(
order[x])와 수량(y)을 곱한 값을ret에 누적합니다.flag가 true라면ret = ret - (ret * discount) / 100으로 할인을 적용합니다.최종 금액
ret을 반환합니다.
C++ 구현 예제
아래 구현 예제를 통해 더 잘 이해해 보겠습니다.
#include <bits/stdc++.h>
using namespace std;
class Cashier {
public:
int curr;
map <double, double> order;
int n;
int discount;
Cashier(int n, int discount, vector<int>& pro, vector<int>& p) {
curr = 0;
for(int i = 0; i < p.size(); i++){
order[pro[i]] = p[i];
}
this->n = n;
this->discount = discount;
}
double getBill(vector<int> pro, vector<int> am) {
curr++;
bool flag = curr == n;
if(curr == n){
curr = 0;
}
double ret = 0;
for(int i = 0; i < pro.size(); i++){
double x = pro[i];
double cost = order[x];
double y = am[i];
ret += (cost * y);
}
if(flag) ret = ret - (ret * discount) / 100;
return ret;
}
};
main(){
vector<int> v1 = {1,2,3,4,5,6,7}, v2 =
{100,200,300,400,300,200,100};
Cashier ob(3, 50, v1, v2);
v1 = {1,2}, v2 = {1,2};
cout << (ob.getBill(v1, v2)) << endl;
v1 = {3,7}, v2 = {10,10};
cout << (ob.getBill(v1, v2)) << endl;
v1 = {1,2,3,4,5,6,7}, v2 = {1,1,1,1,1,1,1};
cout << (ob.getBill(v1, v2)) << endl;
v1 = {4}, v2 = {10};
cout << (ob.getBill(v1, v2)) << endl;
v1 = {7,3}, v2 = {10,10};
cout << (ob.getBill(v1, v2)) << endl;
v1 = {7,5,3,1,6,4,2}, v2 = {10,10,10,9,9,9,7};
cout << (ob.getBill(v1, v2)) << endl;
v1 = {2,3,5}, v2 = {5,2,3};
cout << (ob.getBill(v1, v2)) << endl;
}입력
main 함수 참조
출력
500 4000 800 4000 4000 7350 2500