PAT甲级 1095 cars on campus

题意:先输入两个数,分别是n条信息和k个查询(queries),每条信息包含车牌号,进去(出去)的时间,和该车的状态(status)

思路:用vector v来存所有信息,bool cmp1来排序一次,用来除去无效信息,比如同一辆车有多条输入却只有一条输出,cmp1如果是车牌号相同,放到一组去比,每一组就是某一辆车一整天的状态,同一组根据时间从小到大排序,就是a.id==b.id,return a.time<b.time,这里默认学校刚开始是没有车的,根据这个分组里面的时间顺序,进入后面要跟着出去,根据这个来存放有效的出入时间,累加存放再map(因为可能出入多次),也把这些有效时间对应的信息放到v1里面,时间从小到大排序v1,每一个v1代表一个时间,用一个数组carnum根据v1每个元素的进出状态累加来得出每个时间的车辆数;

注意点:只有如果测试点4不通过,看看是不是最长时间Longtime没有做到累加或者每辆车的停车时间map没有做到累加,只是赋值而已;

代码:

#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<cstring>
using namespace std;
struct node{
	char num[10];//车牌号
	int time;//用秒来算;
	int status=0;//记录车子的状态;
};
bool cmp1(node a, node b) {
    if(strcmp(a.num, b.num) != 0)
        return strcmp(a.num, b.num) < 0;
    else
        return a.time < b.time;
}
bool cmp2(node a,node b){
	return a.time<b.time;
}
int main(){
	int n,k,h,m,s,temptime;
	char temp[5];
	scanf("%d %d",&n,&k);
	vector<node> v(n); 
	for(int i=0;i<n;i++){ 
		scanf("%s %d:%d:%d %s",v[i].num,&h,&m,&s,temp);
		v[i].status=((strcmp(temp,"in")==0)?1:-1);
		temptime=h*3600+m*60+s;//一般涉及到时间比较的题目都是转换成秒数来;
		v[i].time=temptime;
	}
	sort(v.begin(),v.end(),cmp1);
	vector<node> v1;
	map<string,int> mapp;//map用来存有效时间;
	int longtime=-1;
	for(int i=0;i<v.size()-1;i++){
		if(strcmp(v[i].num,v[i+1].num)==0&&v[i].status==1&&v[i+1].status==-1){
			v1.push_back(v[i]);
			v1.push_back(v[i+1]);
			temptime=(v[i+1].time-v[i].time);
			mapp[v[i].num]+=temptime;
			if(longtime<mapp[v[i].num]){
				longtime=mapp[v[i].num];
			}
		}
	}
	sort(v1.begin(),v1.end(),cmp2);
	vector<int >carnum(v1.size());
	for(int i=0;i<v1.size();i++){
		if(i==0){//就算每条时间里面有多少车,出一辆车是-1,进一辆就+1;
			carnum[i]=v1[i].status;
		}else carnum[i]=carnum[i-1]+v1[i].status;//累加(减);
	}
	int now=0;
	for(int i=0;i<k;i++){
		scanf("%d:%d:%d",&h,&m,&s);
		temptime=h*3600+m*60+s; 
		int j;
		for(j=now;j<v1.size();j++){
			if(v1[j].time>temptime){
				printf("%d\n",carnum[j-1]);
				break;
			}else if(j==v1.size()-1){
				printf("%d\n",carnum[j]);
			}
		}
		now=j;//时间是递增的,记下这一次的进程,以免每次都是从头开始遍历而超时;
	}
	for(map<string,int>::iterator it=mapp.begin();it!=mapp.end();it++){
		if(it->second==longtime){
			printf("%s ",it->first.c_str());//printf是c的函数,string
  //是c++的函数,c的函数没办法向上兼容c++,所以c++的string转换成c的char,就是用.c.str();
		}
	}
	printf("%02d:%02d:%02d",longtime/3600,(longtime%3600)/60,longtime%60);
	return 0;
} 

心得:

1.map,map的定义,map<键,值>,健和值可以是任何类型,也可以是自定义的结构体,键和值具有一一对应的映射关系,定义输出map 的迭代器:for(map<键,值>::iterator it=map.begin();it!=map.end();it++);

不想写map<key,value>::iterator 也可以,可以些auto,会自动匹配,如果是刚学的话,多写几次会比较好;

it->first是键值,it->second是值;

map[键]=值;

2.printf,scanf输入输出c++的string,要把string转换成c的char输出,it->first.c.str();

3.sort的功能很强大,可以按照你的想法来排列,不仅仅只局限于从小到大或者从大到小,还可以是分组排列;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值