美团codeM之美团代金券
前天做了下美团的一个codeM比赛的资格赛,遇到一个题目挺有意思的,所以现在做一下总结。
题目描述
美团的每一个用户都有一个用户代金券的消费记录日志,每位用户都能购买若干种代金券,但是每一种代金券最多只能购买一张。如果现在手上已经有了一张某种的代金券,那么只有在消费完这张代金券之后才能再次购买同种代金券。每位用户的购买和消费记录都记录在日志文件中,字符I
代表购买代金券,字符O
代表消费代金券。现在由于系统出现故障,造成了日志文件的损坏,在这个文件中有些记录无法恢复,只能用字符?
代替,现在需要你来检查这个日志文件中的记录是否是合理的,如果出现某些冲突则表示该日志文件出现错误。
例如在某位用户的消费记录日志中的记录是这样的:
I 1
O 1
代表用户首先购买了编号为1的代金券,然后又消费了该代金券,所以该日志文件是正确的。对于正确的日志文件我们输出-1。
如果消费记录是这样的:
I 1
I 1
O 1
因为用户重复购买了编号为1的代金券,这是不合理的,所以这个日志文件有问题,问题出现在第二行,所以我们应该输出2。
如果消费记录是这样的:
?
I 1
O 2
因为这个?
是无法恢复的,所以可以看做是任何可能的记录,在这个例子中我们可以将它视为I 2
,在这样的解释之下,这个日志文件是合理的,所以我们最终的输出是-1。
输入样例
首先我们需要输入一个m
,表明这个日志文件的总的行数。之后就像上述的例子那样的输入。
2
I 1
O 1
3
I 1
I 1
O 1
3
?
I 1
O 2
4
I 1
?
O 1
O 1
输出样例
如果日志文件没有问题那么输出-1,如果有问题则输出最早出现问题的行数。
-1
2
-1
4
解题思路
当时没有想明白具体的逻辑,改了很久都没有过,今天问小崔才明白正确的解题思路。经过分析之后我们知道,输入?
的时候是肯定不会有错误的,错误只能出现在I
与O
的某行。那么当输入为I number
的时候我们需要检查我们是否已经拥有这张代金券,如果没有那么这条记录是没有问题的,如果已经购买了这张代金券我们就应该进一步的检查,看上一次编号为number
的代金券是什么时候买的,如果在这之间有一个?
那么我们可以将这个?
作为一个O number
的记录,这样也就不会产生错误了。同样当输入为O number
的时候我们同样按照相同的思路进行处理,如果有问题我们就应该进一步检查上一个相同编号的消费记录在什么时候,在这段时间内是否有?
,如果有?
我们就可以进行合理解释,否则就是一个错误的消费记录。
解题代码
#include <cstdio>
#include <set>
#include <cstring>
using namespace std;
const int maxn = 100000+10;
int m, number;
char type;
int buy_time[maxn], sale_time[maxn];
bool coupon[maxn];
set<int> unsure;
set<int>::iterator idx;
int main() {
while (~scanf("%d", &m)) {
memset(buy_time, -1, sizeof(buy_time));
memset(sale_time, -1, sizeof(sale_time));
memset(coupon, false, sizeof(coupon));
unsure.clear();
int ans = -1;
for (int i = 1; i <= m; ++i) {
getchar();
scanf("%c", &type);
if (type == '?') {
unsure.insert(i);
} else {
scanf("%d", &number);
if (type == 'I') {
if (!coupon[number]) {
coupon[number] = true;
} else {
// 对处于上一个I与现在这个I之间的第一个?做一个处理,将它作为一个O使用
int preBuyTime = buy_time[number];
idx = unsure.lower_bound(preBuyTime); // 返回preBuyTime之后的第一个?的位置
if (idx != unsure.end()) {
unsure.erase(idx);
} else {
// 如果没有?可以用,那么就是错误情况了
if (ans == -1) {
ans = i;
}
}
}
buy_time[number] = i;
} else {
if (coupon[number]) {
coupon[number] = false;
} else {
// 对处于上一个O与现在这个O之间的第一个?做一个处理,将它作为一个I使用
int preSaleTime = sale_time[number];
idx = unsure.lower_bound(preSaleTime); // 返回preSaleTime之后的第一个?的位置
if (idx != unsure.end()) {
unsure.erase(idx);
} else {
// 如果没有?可以用,那么就是错误情况了
if (ans == -1) {
ans = i;
}
}
}
sale_time[number] = i;
}
}
}
printf("%d\n", ans);
}
return 0;
}
美团codeM之美团代金券的更多相关文章
- LOJ #6192. 「美团 CodeM 复赛」城市网络 (树上倍增)
#6192. 「美团 CodeM 复赛」城市网络 内存限制:64 MiB 时间限制:500 ms 标准输入输出 题目描述 有一个树状的城市网络(即 nnn 个城市由 n−1n-1n−1 条道路连接 ...
- #6164. 「美团 CodeM 初赛 Round A」数列互质-莫队
#6164. 「美团 CodeM 初赛 Round A」数列互质 思路 : 对这个题来言,莫队可以 n*根号n 离线处理出各个数出现个的次数 ,同时可以得到每个次数出现的次数 , 但是还要处理有多少 ...
- LibreOJ #6192. 「美团 CodeM 复赛」城市网络
#6192. 「美团 CodeM 复赛」城市网络 内存限制:64 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: sqc 提交提交记录统计讨论测试数据 题目描 ...
- 美团 CodeM 复赛」城市网络
美团 CodeM 复赛」城市网络 内存限制:64 MiB时间限制:500 ms标准输入输出 题目描述 有一个树状的城市网络(即 nnn 个城市由 n−1n-1n−1 条道路连接的连通图),首都为 11 ...
- [LOJ 6213]「美团 CodeM 决赛」radar
[LOJ 6213]「美团 CodeM 决赛」radar 题意 给定 \(n\) 个横坐标 \(x_i\) , 为它们选择一个不超过 \(y_i\) 的纵坐标 \(h_i\), 产生 \(c_ih_i ...
- LibreOJ #6191. 「美团 CodeM 复赛」配对游戏
二次联通门 : LibreOJ #6191. 「美团 CodeM 复赛」配对游戏 /* LibreOJ #6191. 「美团 CodeM 复赛」配对游戏 概率dp */ #include <cs ...
- LibreOJ #6212. 「美团 CodeM 决赛」melon
二次联通门 : LibreOJ #6212. 「美团 CodeM 决赛」melon /* LibreOJ #6212. 「美团 CodeM 决赛」melon MDZZ 这是决赛题?? */ #incl ...
- 「题解」「美团 CodeM 资格赛」跳格子
目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...
- 【¥200代金券、iPad等您来拿】 阿里云9大产品免费公测#10月9日-11月6日#
#10.09-11.06#200元代金券.iPad大奖, 9大产品评测活动! 亲爱的阿里云小伙伴们: 云产品的多样性(更多的云产品)也是让用户深度使用云计算的关键.今年阿里云产品线越来越丰富,小云搜罗 ...
随机推荐
- 【SIKIA计划】_06_Unity2D游戏开发-拾荒者笔记
[新增分类]Animations 动画——Animation——AnimatorControllerPrefabs 预制 [素材导入]unitypackage 素材包Sprites Editor 编辑 ...
- Django 前后端不分离 代码结构详解
Demo: hello_pycharm 根目录文件:hello_pycharm [__init__.py __pycache__ settings.py urls.py wsgi.py] A ...
- linux go环境安装
方法一 这次将源码包安装的目录是是/root下. 1.官网下载源码包. 官网链接:https://golang.org/dl/ wget https://storage.googleapis.co ...
- linux 常用反弹shell小记
在渗透测试过程中由于防火墙和其它安全防御措施,很多服务器只能单向向外访问,不能被访问,我们常常需要反弹shell. 1.bash反弹shell 本地开启监听 nc -lvvp 受害主机命令 bash ...
- Binary Tree的3种非Recursive遍历
Binary Tree Preorder Traversal Given a binary tree, return the preorder traversal of its nodes' valu ...
- yarn (npm) 切换设置镜像源
设置镜像源 1.查看一下当前源 yarn config get registry 2.切换为淘宝源 yarn config set registry https://registry.npm.taob ...
- MySQL课堂练习 20162315
练习内容 1.参考教材相关代码,提交能连接到world的截图(有学号水印) 2.查询world数据库,获得人口超过500万的所有城市的列表. 3.查询world数据库,获得New Jersey州所有城 ...
- web09 struts2配置 struts2入门
电影网站:www.aikan66.com 项目网站:www.aikan66.com游戏网站:www.aikan66.com图片网站:www.aikan66.com书籍网站:www.aikan66.co ...
- ubuntu下安装matlab2015b
========= 安装过程 1.下载MATLAB2015b破解版 操作系统:Ubuntu 16.04 LTS 程序文件:Matlab2015b-glnxa64破解版 解压提取文件:在ubuntu系统 ...
- 一个关于狗记录的Java练习
package 狗场;import java.util.*;public class dogRoom { /** * 作者.范铭祥 * 狗场的狗体重查询问题 */ public static void ...