拼多多笔试编程第三题

【题目来自牛客】
代码较多,有注释

[编程|25分] 简单易懂的秒杀服务

实现一个简易的秒杀服务,有3个接口:

1. 添加一个秒杀活动 addActivity(int startTime, int endTime, int goodsId, int limitQuantity)

参数说明:

    * 时间区间为左闭右开:[startTime, endTime) 。数据保证 startTime < endTime,startTime 大于当前时间戳
    * goodsId 一定为存在的商品id。每个goodsId至多添加一次秒杀活动。
    * limitQuantity > 0 

返回值有以下两种情况:

    * 添加成功,返回秒杀活动ID (从0开始自增)
    * 秒杀商品数量大于商品库存,添加失败,返回-1

2. 购买秒杀商品 buyGoods(int activityId, int quantity)

参数说明:

    * activityId 一定是请求时存在的活动id
    * quantity > 0 

返回值有以下三种情况:

    * 购买成功,减少库存,返回0
    * 购买数量大于秒杀商品剩余数量,购买失败,返回-1
    * 秒杀未开始或已结束,购买失败,返回-1

3. 获取秒杀活动列表 getActivityList() 获取当前时刻的秒杀活动列表

秒杀列表排序方式:进行中(未售罄) > 进行中(售罄) > 未开始 

    * 对于「进行中(未售罄)」:依次按商品人气值从高到低、商品ID从小到大排序 
    * 对于「进行中(已售罄)」:依次按最后卖出时间从晚到早、商品人气值从高到低、商品ID从小到大排序 
    * 对于「未开始」:依次按开始时间从早到晚、商品人气值从高到低、商品ID从小到大排序
    * 对于已结束的秒杀,不返回。 

返回秒杀活动id列表

商品拥有以下属性:

* 商品ID,32位非负整数 
* 人气值,32位非负整数 
* 库存,32位非负整数

现给出一串请求,每个请求的格式为:时间戳 函数名 参数。请对每个请求都输出其返回结果 (请求已经按照时间先后顺序排序过) 。

数据范围:

* 商品数量 N <= 10,000
* 请求数量 M <= 10,000
* add 数量 A <= 1,000
* buy 数量 B <= 10,000 
* list 数量 L <= 100

输入描述:

第一行是两个整数 N 和 M ,分别表示商品数量和请求数量。
接下来有 N 行,每行表示一个商品,具体格式为:3个整数(被空格分隔)分别表示商品ID,人气值,库存
接下来有 M 行,每行表示一个请求,请求已经按时间戳从小到大排序。
具体格式为:时间戳 请求类型 请求参数...
  * 时间戳:正整数
  * 请求类型,共三种:"add", "buy" 和 "list"
  * 请求参数:按题目描述中的顺序,参数之间空格分隔

输出描述:

对每个请求,输出其返回值,一个请求的输出占一行:
  * add:成功输出id,失败输出-1
  * buy:成功输出0,失败输出-1
  * list:输出活动id列表,按要求的顺序,相邻数字之间用一个空格分隔。若列表为空,则输出空行。

示例1

输入

6 13
1001 1 10
1002 1 10
1003 2 10
1004 2 10
1005 2 10
1006 3 10
1 add 2 20 1001 10
2 buy 0 1
3 buy 0 10
4 add 5 6 1002 2
5 list
6 buy 1 1
7 add 10 20 1003 11
8 add 10 20 1003 8
9 add 10 20 1004 3
10 add 11 20 1005 5
11 add 20 30 1006 1
12 buy 3 3
13 list

输出

0
0
-1
1
0 1
-1
-1
2
3
4
5
0
2 4 0 3 5

#include "bits/stdc++.h"
using namespace std;

struct goods{
	goods() :goodsId(0), sellDoneTime(INT_MAX), activityId(-1), Populity(0), LimitQuility(0), Left(0), startTime(0), endTime(0), LIMIT_TAG(0){};
	int goodsId;
	int Populity;
	int Left;
	int LimitQuility;
	int startTime, endTime;
	int LIMIT_TAG;
	int activityId;
	int sellDoneTime;
	//0未开始 1已开始  2卖光 -1已结束
};

bool cmp1(const goods &lsh, const goods &rsh){
	return lsh.Populity > rsh.Populity || (lsh.Populity == rsh.Populity && lsh.goodsId < rsh.goodsId);
}
bool cmp0(const goods &lsh, const goods &rsh){
	return lsh.startTime < rsh.startTime || (lsh.startTime== rsh.startTime && lsh.Populity > rsh.Populity) ||
		(lsh.startTime == rsh.startTime && lsh.Populity == rsh.Populity && lsh.goodsId < rsh.goodsId);}
bool cmp2(const goods &lsh, const goods &rsh){
	return lsh.sellDoneTime > rsh.sellDoneTime || (lsh.startTime == rsh.startTime && lsh.Populity > rsh.Populity) ||
		(lsh.startTime == rsh.startTime && lsh.Populity == rsh.Populity && lsh.goodsId < rsh.goodsId);
}

struct MS{
	MS(int n){
		AllThing = vector<goods>(n);
		t_id = -1;
	};
	int addActivity(int startTime, int endTime, int goodsld, int limitQuantity);
	int buyGoods(int activityId, int quantity, int time);
	void getActivityList(int time);
	vector<goods> AllThing;
	vector<goods> LimitVEC;
	int t_id;
};

int MS::addActivity(int startTime, int endTime, int goodsld, int limitQuantity){
	int i;
	for (i = 0; i < AllThing.size(); i++){
		if (AllThing[i].goodsId == goodsld)
		{
			break;
		}
	}
	if (i >= AllThing.size() || AllThing[i].Left < limitQuantity || AllThing[i].LIMIT_TAG)
	{
		//无法秒杀
		cout << "-1" << endl;
		return -1;
	}
	AllThing[i].Left -= limitQuantity;
	AllThing[i].LIMIT_TAG = 1; 
	AllThing[i].startTime = startTime;
	AllThing[i].endTime = endTime;
	AllThing[i].LimitQuility = limitQuantity;
	AllThing[i].activityId = ++t_id;;
	LimitVEC.push_back(AllThing[i]);
	cout << t_id << endl;
	return  t_id;
}

int MS::buyGoods(int activityId, int quantity, int time){
	if (activityId >= LimitVEC.size() ||quantity > LimitVEC[activityId].LimitQuility|| time < LimitVEC[activityId].startTime || time >= LimitVEC[activityId].endTime)
	{
		cout << "-1" << endl;
		return -1;
	}
	LimitVEC[activityId].LimitQuility -= quantity;
	if (LimitVEC[activityId].LimitQuility == 0)
	{
		LimitVEC[activityId].LIMIT_TAG = 2;
		LimitVEC[activityId].sellDoneTime = time;
	}
	cout << "0" << endl;
	return 0;
}

void MS::getActivityList(int time){
	vector<goods> VEC0;
	vector<goods> VEC1;
	vector<goods> VEC2;
	for (int i = 0; i < LimitVEC.size();i++)
	{
		//没开始
		if (LimitVEC[i].LIMIT_TAG == 1 && LimitVEC[i].startTime > time){
			VEC0.push_back(LimitVEC[i]);
		}
		//结束了
		else if (LimitVEC[i].LIMIT_TAG > 0&& LimitVEC[i].endTime <= time){
		}
		//没卖完
		else if (LimitVEC[i].LIMIT_TAG == 1 && LimitVEC[i].endTime > time)
		{
			VEC1.push_back(LimitVEC[i]);
		}
		else if (LimitVEC[i].LIMIT_TAG == 2){
			VEC2.push_back(LimitVEC[i]);
		}
	}
	if (!VEC1.empty())
	{
		sort(VEC1.begin(), VEC1.end(), cmp1);
	}
	if (!VEC2.empty())
	{
		sort(VEC2.begin(), VEC2.end(), cmp2);
	}
	if (!VEC0.empty())
	{
		sort(VEC0.begin(), VEC0.end(), cmp0);
	}
	VEC1.insert(VEC1.end(), VEC2.begin(), VEC2.end());
	VEC1.insert(VEC1.end(), VEC0.begin(), VEC0.end());
	if (!VEC1.empty()){
		for (int i = 0; i < (int)VEC1.size() - 1; i++)
			cout << VEC1[i].activityId << " ";
		cout << VEC1[VEC1.size() - 1].activityId << endl;
	}
	
}

int main(){
	int n,m;
	cin >> n >> m;
	MS ms(n);
	map<string, int> MP;
	MP["add"] = 0;
	MP["buy"] = 1;
	MP["list"] = 2;
	for (int i = 0; i < n;i++)
	{
		cin >> ms.AllThing[i].goodsId >> ms.AllThing[i].Populity >> ms.AllThing[i].Left;
	}
	for (int i = 0; i < m;i++)
	{
		int time,a,b,c,d;
		string ope;
		cin >> time >> ope;

		switch (MP[ope]){
		//add
		case 0:
			cin >> a >> b >> c>>d;
			ms.addActivity(a, b, c, d);
			break;
		//buy
		case 1:
			cin >> a >> b;
			ms.buyGoods(a, b, time);
			break;
		//list
		case 2:
			ms.getActivityList(time);
			break;
		}
	}
	return 0;
}


全部评论
🐮
点赞 回复 分享
发布于 2017-09-02 20:51
惊呆了
点赞 回复 分享
发布于 2017-09-02 21:03
这是哪个岗位?
点赞 回复 分享
发布于 2017-09-02 21:19

相关推荐

一面1.&nbsp;go基本八股,有线程和协程的区别(我答的一般,感觉这里可以联系gmp),三色标记法,如何通知goroutine让其关闭,map的底层结构2.&nbsp;mysql基本八股,几种并发问题,对应怎么解决的,索引的结构,你是怎么建立索引的等等(记不太清了)3.&nbsp;mysql执行一条语句的时候突然变得很慢,如何去优化,列举一下可能的原因4.&nbsp;gin框架为什么快5.&nbsp;redis的基本八股,几种数据结构,zset底层6.&nbsp;问简历上一些项目相关的技术以及具体实现7.&nbsp;手撕插入区间,思路没问题,但是边界没处理后越界了二面当天就约了二面,我给推到下周一了。二面问的也不是特别难,可以说是八股进阶吧。1.&nbsp;go八股必不可少2.&nbsp;聊项目,具体怎么实现的,有什么难题,怎么解决的3.&nbsp;redis的集群方案,描述几种方式的架构,再说一些优缺点4.&nbsp;手撕合并两个有序链表(怎么才easy,我准备算法的时间最长了)5.&nbsp;聊了聊实习岗位的业务以及相关技术栈6.&nbsp;面试官当场说oc了,几分钟后hr电话来了魔门塔(‌Momenta)‌不是外企也不是国企,‌而是一家民营科技企业‌。‌以下是关于魔门塔的详细背景信息:‌‌性质‌:‌民营科技企业、‌独角兽企业、‌高新技术企业。‌‌成立时间‌:‌2016年12月(‌北京公司)‌,‌2018年6月(‌苏州公司)‌。‌‌注册资本‌:‌北京公司注册资本为88997.215万人民币,‌苏州公司为84905.7108万美元。‌‌经营范围‌:‌包括科技领域内的技术开发、‌技术推广、‌技术转让、‌技术咨询、‌技术服务等,‌涉及自动驾驶、‌人工智能、‌汽车智能化等领域。‌‌投资与合作‌:‌曾获得多轮融资,‌包括通用汽车的投资,‌用于加速自动驾驶技术的研发和应用。‌总结!实力雄厚!!!!!自动驾驶独角兽Momenta2025届校园招聘开启【公司介绍】Momenta是全球领先的自动驾驶公司,致力于通过突破性的AI科技,创造更美好的生活。【岗位需求】算法、后端开发、前端开发、嵌入式开发、架构集成、中间件开发、系统研发【薪酬待遇】行业独角兽有竞争力的薪资+免费三餐、弹性工作不打卡、米哈游、福利奖金、六险一金、带薪假期、社团活动、定期体检、免费健身房、更多福利等你解锁!【工作地点】苏州、北京、上海、深圳【内推链接】https://momenta.jobs.feishu.cn/s/irAa1chE内推码:YRHKRW8(后续有流程/面试时间上的问题,欢迎随时联系)&nbsp;投递的uu留下姓名缩写和岗位~我会一一跟进~
Momenta
|
校招
|
24个岗位
点赞 评论 收藏
分享
点赞 9 评论
分享
牛客网
牛客企业服务