PAT甲题题解-1095. Cars on Campus(30)-(map+树状数组,或者模拟)
题意:给出n个车辆进出校园的记录,以及k个时间点,让你回答每个时间点校园内的车辆数,最后输出在校园内停留的总时间最长的车牌号和停留时间,如果不止一个,车牌号按字典序输出。
几个注意点:
1.如果一个车连续多次进入,只取最后一个
2.如果一个车连续多次出去,只取第一个
3.一个车可能出入校园内好几次,停留时间取总和
实际上题目就是让我们求某个时间段内的车辆总和,时间段其实就相当于一个区间,区间求和的话,很快就联想到树状数组和线段树。然而怎么将时间段和区间联系起来呢,那就存储出现在记录和询问里的所有时间点,从小到大排序,索引即为区间中节点的编号。
那么问题就转化为车辆停留的时间对应区间[l,r],该区间内每个时间点的车辆数都+1,询问就是求某个点的值。这里就采用了树状数组的“区间更新,单点查询”,不理解的可以参考下面链接:
http://www.cnblogs.com/chenxiwenruo/p/3430920.html
- #include <iostream>
- #include <cstdio>
- #include <algorithm>
- #include <string.h>
- #include <string>
- #include <map>
- /*
- 有时候第五个样例会超时,限时220ms,运行的话208ms。
- */
- using namespace std;
- const int maxn=+;
- string timeline[maxn]; //存储出现的时间
- string query[maxn];
- int parking[maxn]; //树状数组,用于统计区间内的车辆数
- int timecnt=;
- map<string,int>visnumber; //记录出现的车牌号
- map<string,int>vistime; //记录出现的每个时间点
- struct Record{
- string plate_number;
- string time;
- char status[];
- bool operator<(const Record tmp)const{
- //不知道为啥,原本<=0就会导致在第3、6个样例段中对record的sort排序产生段错误
- if(time.compare(tmp.time)<)
- return true;
- else
- return false;
- }
- }record[maxn];
- struct Car{
- string plate_number;
- //char time[10];
- int l,r;
- int timelength=;
- bool operator<(const Car tmp)const{
- if(timelength==tmp.timelength){
- if(plate_number.compare(tmp.plate_number)<=)
- return true;
- else
- return false;
- }
- else
- return timelength>tmp.timelength;
- }
- }car[maxn];
- /*
- 二分查找某个时间点对应的索引
- */
- int binarySearch(string str){
- int l=,r=timecnt,mid;
- while(r>=l){
- mid=(l+r)>>;
- if(str.compare(timeline[mid])==)
- return mid;
- if(str.compare(timeline[mid])<){
- r=mid-;
- }
- else{
- l=mid+;
- }
- }
- return -;
- }
- //以下三个函数为树状数组的操作
- int lowbit(int x){
- return x&(-x);
- }
- /*
- 区间更新
- */
- void update(int x,int val){
- while(x){
- parking[x]+=val;
- x-=lowbit(x);
- }
- }
- /*
- 单点求和
- */
- int sum(int x){
- int sum=;
- while(x<maxn){
- sum+=parking[x];
- x+=lowbit(x);
- }
- return sum;
- }
- int main()
- {
- int n,k;
- scanf("%d %d",&n,&k);
- for(int i=;i<=n;i++){
- cin>>record[i].plate_number>>record[i].time;
- scanf("%s",record[i].status);
- }
- sort(record+,record+n+);
- timecnt=;
- timeline[++timecnt]="00:00:00";
- vistime["00:00:00"]=;
- timeline[++timecnt]="23:59:59";
- vistime["23:59:59"]=;
- for(int i=;i<=n;i++){
- if(!vistime[record[i].time]){
- vistime[record[i].time]=;
- timeline[++timecnt]=record[i].time;
- }
- }
- for(int i=;i<k;i++){
- cin>>query[i];
- if(!vistime[query[i]]){
- timeline[++timecnt]=query[i];
- vistime[query[i]]=;
- }
- }
- sort(timeline+,timeline+timecnt+);
- int carcnt=;
- /*
- 求每辆车进出校园对应的时间区间段,以及停留的时间
- 同一辆车连续多次进入,取最后一个。
- 同一辆车连续多次出去,取第一个。
- */
- for(int i=;i<=n;i++){
- if(record[i].status[]=='i'){
- visnumber[record[i].plate_number]=i;
- }
- else if(visnumber[record[i].plate_number]!= && record[i].status[]=='o'){
- int in=visnumber[record[i].plate_number];
- car[carcnt].plate_number=record[i].plate_number;
- car[carcnt].l=binarySearch(record[in].time);
- car[carcnt].r=binarySearch(record[i].time);
- int hh1,mm1,ss1;
- int hh2,mm2,ss2;
- hh2=(record[i].time[]-'')*+(record[i].time[]-'');
- mm2=(record[i].time[]-'')*+(record[i].time[]-'');
- ss2=(record[i].time[]-'')*+(record[i].time[]-'');
- hh1=(record[in].time[]-'')*+(record[in].time[]-'');
- mm1=(record[in].time[]-'')*+(record[in].time[]-'');
- ss1=(record[in].time[]-'')*+(record[in].time[]-'');
- car[carcnt].timelength=(hh2*+mm2*+ss2)-(hh1*+mm1*+ss1);
- visnumber[record[i].plate_number]=; //这样做是可能后来该车又进来
- carcnt++;
- }
- }
- memset(parking,,sizeof(parking));
- /*
- 如果某辆车l进、r出,则对应区间段[l,r-1]的车辆数+1
- */
- for(int i=;i<carcnt;i++){
- int l=car[i].l;
- int r=car[i].r;
- //更新[l,r-1),该区间内每个时间段数量都+1。相当于[1,r-1]的先+1,[1,l-1]的再-1
- update(r-,);
- update(l-,-);
- }
- //求对应某个时间点,校园的车辆数
- for(int i=;i<k;i++){
- int idx=binarySearch(query[i]);
- printf("%d\n",sum(idx));
- }
- visnumber.clear();
- //有可能一辆车进出校园好几次,所以要将停留的时间累加
- for(int i=;i<carcnt;i++){
- if(!visnumber[car[i].plate_number]){
- visnumber[car[i].plate_number]=i;
- }
- else{
- int idx=visnumber[car[i].plate_number];
- car[idx].timelength+=car[i].timelength;
- }
- }
- sort(car,car+carcnt);
- cout<<car[].plate_number;
- for(int i=;i<carcnt;i++){
- if(car[i].timelength==car[].timelength){
- cout<<" "<<car[i].plate_number;
- }
- }
- int h=car[].timelength/;
- int m=(car[].timelength%)/;
- int s=car[].timelength%;
- printf(" %02d:%02d:%02d\n",h,m,s);
- return ;
- }
(其实这题也可以纯按模拟题来做,用树状数组有点大材小用了,按照记录的时间排序,模拟车辆的进出,用一个变量记录校园当前的车辆数量。)
PAT甲题题解-1095. Cars on Campus(30)-(map+树状数组,或者模拟)的更多相关文章
- PAT (Advanced Level) Practise - 1095. Cars on Campus (30)
http://www.patest.cn/contests/pat-a-practise/1095 Zhejiang University has 6 campuses and a lot of ga ...
- PAT甲题题解-1068. Find More Coins (30)-dp,01背包
一开始没多想,虽然注意到数据N<=10^4的范围,想PAT的应该不会超时吧,就理所当然地用dfs做了,结果最后一组真的超时了.剪枝啥的还是过不了,就意识到肯定不是用dfs做了.直到看到别人说用0 ...
- PAT甲题题解-1014. Waiting in Line (30)-模拟,优先级队列
题意:n个窗口,每个窗口可以排m人.有k为顾客需要办理业务,给出了每个客户的办理业务时间.银行在8点开始服务,如果窗口都排满了,客户就得在黄线外等候.如果有一个窗口用户服务结束,黄线外的客户就进来一个 ...
- PAT甲题题解-1076. Forwards on Weibo (30)-BFS
题目大意:给出每个用户id关注的人,和转发最多的层数L,求一个id发了条微博最多会有多少个人转发,每个人只考虑转发一次.用BFS,同时每个节点要记录下所在的层数,由于只能转发一次,所以每个节点要用vi ...
- PAT甲题题解-1112. Stucked Keyboard (20)-(map应用)
题意:给定一个k,键盘里有些键盘卡住了,按一次会打出k次,要求找出可能的坏键,按发现的顺序输出,并且输出正确的字符串顺序. map<char,int>用来标记一个键是否为坏键,一开始的时候 ...
- PAT甲题题解-1119. Pre- and Post-order Traversals (30)-(根据前序、后序求中序)
(先说一句,题目还不错,很值得动手思考并且去实现.) 题意:根据前序遍历和后序遍历建树,输出中序遍历序列,序列可能不唯一,输出其中一个即可. 已知前序遍历和后序遍历序列,是无法确定一棵二叉树的,原因在 ...
- 【题解】BZOJ4548 小奇的糖果(树状数组)
[题解]BZOJ4548 小奇的糖果(树状数组) 说在前面:我有个同学叫小奇,他有一个朋友叫达达,达达特爱地理和旅游,初中经常AK地理,好怀恋和他已经达达一起到当时初中附近许多楼盘的顶楼逛的时光... ...
- 【题解】Leyni,罗莉和队列(树状数组)
[题解]Leyni,罗莉和队列(树状数组) HRBUST - 1356 将整个序列reverse一下,现在就变成了从高到低的排队.题目就变成了,定位一个妹子,问这个妹子前面的比这个妹子小的妹子中,下标 ...
- 【题解】P1972 [SDOI2009]HH的项链 - 树状数组
P1972 [SDOI2009]HH的项链 声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 题目描述 \(HH\) 有一串由各种 ...
随机推荐
- 利用MSF的MS08_067模块攻击windows server 2003 SP2中文版系统
一.测试环境 攻击机:kali(NMAP+MSF) 靶机:windows server 2003 SP2 中文版 利用漏洞:MS08_067 二.漏洞描述 MS08-067漏洞的全称为“Windows ...
- BZOJ4340:[BJOI2015]隐身术(后缀数组,ST表,DFS)
Description 给定两个串A,B.请问B中有多少个非空子串和A的编辑距离不超过K? 所谓“子串”,指的是B中连续的一段.不同位置的内容相同的子串算作多个. 两个串之间的“编辑距离”指的是把一个 ...
- [luogu2172] 部落战争
题面 我们可以将'.'抽象为一个可以通过的点, 将'x'抽象为一个不可通过的点. 那么题意便可以转化为: 一条路径可以看做从任意一个没有到达过的可通过的点出发到任意一个其他的可以通过却没有被到 ...
- linux网络工具iproute2的使用简介
一.写本文的目的 本文完全是自己在学习iproute2的过程中搜集的大杂烩,记录在这里,方便以后自己查询学习,图片都是来自网络,在此表示感谢! 二.简单了解iproute2工具套装 iproute2是 ...
- [转]opengl入门例题(读取bmp图片,并显示)
#include<gl/glut.h> #define FileName "bliss.bmp" static GLint imagewidth; static GLi ...
- JS编写简单的弹窗插件(含有demo和源码)
最近项目做完了 事情不是很多,今天正好也在调休,所以趁着这个时间研究了一下简易的JS弹窗功能,当然网上这块插件非常多,本人也没有仔细看网上的插件源码 只是凭着日常使用过的弹窗插件有这么多功能 来实现自 ...
- 我的$OI$
我只是懒得写日记啦\(\color{pink}{qwq}\) //11月8日 啊--终于要\(NOIp\)了,为此期盼了好久.紧张了好久的我,不知道会迎来怎样的结果. 我只知道这段回忆是值得保留封存的 ...
- Android failed to start daemon
异常描述:在Eclipse中运行Android项目时Console中出现: The connection to adb is down, and a severe error has occured. ...
- PRML5-神经网络(1)
本节来自<pattern recognition and machine learning>第5章. 五.神经网络 在本书的第3.4章分别是基于回归和分类的线性模型,都是通过将固定的基函数 ...
- maven中添加jetty运行插件
maven项目,用jetty插件运行,对热部署的支持比较好.maven的pom文件加入下面代码 <plugin> <groupId>org.mortbay.je ...