「云闪付」作为各方联手打造的全新移动端统一入口,致力成为消费者省钱省心的移动支付管家。
请你设计一个「云闪付」优惠活动管理系统 DiscountSystem
,具体功能如下:
AddActivity(int actId, int priceLimit, int discount, int number, int userLimit)
-- 表示创建编号为actId
的优惠减免活动:- 单笔消费的原价不小于
priceLimit
时,可享受discount
的减免 - 每个用户最多参与该优惠活动
userLimit
次 - 该优惠活动共有
number
数量的参加名额
- 单笔消费的原价不小于
RemoveActivity(actId)
-- 表示结束编号为actId
的优惠活动Consume(int userId, int cost)
-- 表示用户userId
产生了一笔原价为cost
的消费。请返回用户的实际支付金额。- 单次消费最多可参加一份优惠活动
- 若可享受优惠减免,则 「支付金额 = 原价 - 优惠减免」
- 若同时满足多个优惠活动时,则优先参加优惠减免最大的活动
注:若有多个优惠减免最大的活动,优先参加
actId
最小的活动
注意:
actId
全局唯一
示例 1:
输入:
["DiscountSystem","addActivity","consume","removeActivity","consume"]
[[],[1,15,5,7,2],[101,16],[1],[102,19]]
输出:
[null,null,11,null,19]
解释:
DiscountSystem obj = DiscountSystem(); // 初始化系统
obj.addActicity(1,15,5,7,2); //创建编号1
的优惠活动,单笔消费原价不小于15
时,
可享受5
的减免,优惠活动共有7
个名额,每个用户最多参与该活动2
次
obj.consume(101,16); //用户101
消费了16
,满足优惠活动1
条件,返回实际支付16 - 5 = 11
obj.removeActivity(1); // 结束编号为1
的优惠活动
obj.consume(102,19); //用户101
消费了19
,目前不存在任何优惠活动,需按原价支付,返回19
示例 2:
输入:
["DiscountSystem","addActivity","addActivity","consume","removeActivity","consume","consume","consume","consume"]
[[],[1,10,6,3,2],[2,15,8,8,2],[101,13],[2],[101,17],[101,11],[102,16],[102,21]]
输出:
[null,null,null,7,null,11,11,10,21]
解释:
DiscountSystem obj = DiscountSystem(); // 初始化系统
obj.addActivity(1,10,6,3,2); // 创建编号1
的优惠活动,单笔消费原价不小于10
时,
可享受6
的减免,优惠活动共有3
个名额,每个用户最多参与该活动2
次
obj.addActivity(2,15,8,8,2); // 创建编号2
的优惠活动,单笔消费原价不小于15
时,
可享受8
的减免,优惠活动共有8
个名额,每个用户最多参与该活动2
次
obj.consume(101,13); // 用户101
消费了13
,仅满足优惠活动1
条件,返回实际支付13 - 6 = 7
用户101
参加1
次活动1
,活动1
剩余2
个名额
obj.consume(101,8); // 用户101
消费了8
,不满足任何活动,返回支付原价8
obj.removeActivity(2); // 结束编号为2
的活动
obj.consume(101,17); // 用户101
消费了17
,满足优惠活动1
条件,返回实际支付17 - 6 = 11
用户101
参加2
次活动1
,活动1
剩余1
个名额
obj.consume(101,11); // 用户101
消费了11
,满足优惠活动1
条件,但已达到参加次数限制,返回支付原价11
obj.consume(102,16); // 用户102
消费了16
,满足优惠活动1
条件,返回实际支付16 - 6 = 10
用户102
参加1
次活动1
,活动1
无剩余名额
obj.consume(102,21); // 用户102
消费了21
,满足优惠活动1
条件,但活动1
已无剩余名额,返回支付原价21
提示:
1 <= addActicity, removeActivity, consume 累计操作数 <= 10^3
0 <= actId, userId <= 1000
1 <= discount < priceLimit <= 10^5
1 <= cost <= 10^5
1 <= number <= 1000
1 <= userLimit <= 10
C++
class DiscountSystem {
public:
DiscountSystem() {
}
void addActivity(int actId, int priceLimit, int discount, int number, int userLimit) {
mp[actId]={priceLimit, discount, number, userLimit};
}
void removeActivity(int actId) {
mp.erase(actId);
tmp.erase(actId);
}
int consume(int userId, int cost) {
int idx=-1;
for(auto it:mp) {
int actId=it.first;
if(cost>=it.second[0] && it.second[2]>0 && (tmp.find(actId)==tmp.end() || tmp[actId][userId]<it.second[3])) {
idx=actId;
break;
}
}
if(idx==-1) {
return cost;
}
int discount=mp[idx][1];
for(auto it:mp) {
int actId=it.first;
if(cost>=it.second[0] && it.second[1]>discount && it.second[2]>0 && (tmp.find(actId)==tmp.end() || tmp[actId][userId]<it.second[3])) {
idx=actId;
discount=mp[idx][1];
}
}
mp[idx][2]--;
tmp[idx][userId]++;
return cost-discount;
}
private:
map<int,vector<int>> mp;
map<int,map<int,int>> tmp; //key:actId value:uesrId->num
};
/**
* Your DiscountSystem object will be instantiated and called as such:
* DiscountSystem* obj = new DiscountSystem();
* obj->addActivity(actId,priceLimit,discount,number,userLimit);
* obj->removeActivity(actId);
* int param_3 = obj->consume(userId,cost);
*/