题目描述
知识点
STL之priority_queue
实现
码前思考
- 时间最好用秒数
s
来记录 - 需要记录到来时间,开始服务时间和结束服务时间;
- 记得考虑一个用户运气好,来的时候不用等;
- 记得按来的时间排序;
代码实现
//每个window一个人,单人占用部分超过60min
//没有同时到达的客户,就是说大家是有先后次序的!队列
//超过17:00之后来,不当做人看,之前都当作人看,直接忽略
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 1e4+10;
int n;
int k;
int totWait;
int cnt = 0;
struct p{
//以秒进行计数
int ctime;
int stime;
int etime;
int last;
friend bool operator < (p a,p b){
//先结束的,先出来
return a.etime > b.etime;
}
}ps[maxn];
priority_queue<p> q;
bool cmp(p a,p b){
return a.ctime < b.ctime;
}
int main(){
int openTime = 8*60*60;
int closeTime = 17*60*60;
scanf("%d %d",&n,&k);
for(int i=0;i<n;i++){
int hh;
int mm;
int ss;
int last;
scanf("%d:%d:%d %d",&hh,&mm,&ss,&last);
last = last * 60;
int ctime = hh * 60 * 60+ mm * 60 + ss;
p tmp;
if(ctime <= closeTime){//要等于
tmp.ctime = ctime;
tmp.last = last;
ps[cnt++] = tmp;
}else{
continue;
}
}
sort(ps,ps+cnt,cmp);
// for(int i=0;i<cnt;i++){
// printf("%d %d\n",ps[i].ctime,ps[i].last);
// }
//针对cnt进行计算
int idx = 0;
for(;idx<cnt && idx<k;idx++){
//如果是在开门之前来的,则有等待
if(ps[idx].ctime < openTime){
totWait += openTime - ps[idx].ctime;
ps[idx].stime = openTime;
}else{
//不用等
ps[idx].stime = ps[idx].ctime;
}
ps[idx].etime = ps[idx].stime+ps[idx].last;
q.push(ps[idx]);
}
while(idx<cnt){
//接下来就是求解了
p tmp = q.top();
q.pop();
//需要进行一个比较,如果这个可以服务时间和你到的时间有问题
int canTime = tmp.etime;
if(ps[idx].ctime < canTime){
totWait += canTime - ps[idx].ctime;
ps[idx].stime = canTime;
}else{
ps[idx].stime = ps[idx].ctime;
}
ps[idx].etime = ps[idx].stime+ps[idx].last;
q.push(ps[idx]);
idx++;
}
printf("%.1f",totWait*1.0/60/cnt);
return 0;
}
码后反思
- 主要是考察优先队列的使用。
二刷代码
- 二刷的代码没有一刷那么清晰明了。。。我退步了;
- 一刷的时候我有提醒自己要注意不用等的情况,但是二刷的时候两个循环都忘记考虑不要等的时候,结束时间就是到达时间加运行时间;
- 我的代码里面有很多硬编码。。。比如银行的营业范围。
- 对于17点以后的,在一开始就不放入
vector
为好; - 结构体用的也不太好,省略了太多关键信息了,不太好。。。
- 结构体构造函数反而使代码变复杂了,不行啊
//纯粹考察STL的使用
//时间用秒来表示
//入队列时就统计等待时间
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
struct node{
int atime;
int ptime;
int etime;
node(){}
node(int a,int p):atime(a),ptime(p),etime(-1){}
node(int a,int p,int e):atime(a),ptime(p),etime(e){}
friend bool operator < (node a,node b){
return a.etime > b.etime;//注意这里是大于号,和cmp是不同的
}
};
int n;
int k;
double totwait=0.0;
vector<node> lst;
priority_queue<node> q;
bool cmp(node a,node b){
return a.atime < b.atime;
}
int main(){
//freopen("input.txt","r",stdin);
scanf("%d %d",&n,&k);
for(int i=0;i<n;i++){
int hh,mm,ss,p;
scanf("%d:%d:%d %d",&hh,&mm,&ss,&p);
lst.push_back(node(hh*60*60+mm*60+ss,p*60));
}
sort(lst.begin(),lst.end(),cmp);//按照到达时间排序
//接下来首先进队列一些人
int idx;
for(idx=0;idx<k&&idx<lst.size()&&lst[idx].atime < 17*60*60+1;idx++){//注意这个范围啊,要小于lst
if(lst[idx].atime < 8*60*60){
totwait += 8*60*60-lst[idx].atime;//需要等待的
q.push(node(lst[idx].atime,lst[idx].ptime,8*60*60+lst[idx].ptime));
}else{
//然后入队
q.push(node(lst[idx].atime,lst[idx].ptime,lst[idx].atime+lst[idx].ptime));
}
}
//接下来就是不停的出队列,入队列
while(!q.empty() && idx < lst.size() && lst[idx].atime < 17*60*60+1){
node out = q.top(); //队列是不可能提前为空的?
node cur = lst[idx];
//计算等待时间
if(cur.atime < out.etime){
totwait += out.etime - cur.atime;
q.push(node(cur.atime,cur.ptime,out.etime+cur.ptime));//注意结束时间
}else{
q.push(node(cur.atime,cur.ptime,cur.atime+cur.ptime));//注意结束时间
}
q.pop();//记得弹出
idx++;
}
printf("%.1f",totwait/idx/60);
return 0;
}
改一下:
//纯粹考察STL的使用
//时间用秒来表示
//入队列时就统计等待时间
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
struct node{
int atime;
int ptime;
int etime;
node(){}
node(int a,int p):atime(a),ptime(p),etime(-1){}
node(int a,int p,int e):atime(a),ptime(p),etime(e){}
friend bool operator < (node a,node b){
return a.etime > b.etime;//注意这里是大于号,和cmp是不同的
}
};
int n;
int k;
double totwait=0.0;
vector<node> lst;
priority_queue<node> q;
int opentime = 8*60*60;
int closetime = 17*60*60;
bool cmp(node a,node b){
return a.atime < b.atime;
}
int main(){
//freopen("input.txt","r",stdin);
scanf("%d %d",&n,&k);
for(int i=0;i<n;i++){
int hh,mm,ss,p;
scanf("%d:%d:%d %d",&hh,&mm,&ss,&p);
if(hh*60*60+mm*60+ss <= closetime){
lst.push_back(node(hh*60*60+mm*60+ss,p*60));
}
}
sort(lst.begin(),lst.end(),cmp);//按照到达时间排序
//接下来首先进队列一些人
int idx;
for(idx=0;idx<k&&idx<lst.size();idx++){//注意这个范围啊,要小于lst
if(lst[idx].atime < opentime){
totwait += opentime-lst[idx].atime;//需要等待的
q.push(node(lst[idx].atime,lst[idx].ptime,opentime+lst[idx].ptime));
}else{
//然后入队
q.push(node(lst[idx].atime,lst[idx].ptime,lst[idx].atime+lst[idx].ptime));
}
}
//接下来就是不停的出队列,入队列
while(idx < lst.size()){
node out = q.top(); //队列是不可能提前为空的?
node cur = lst[idx];
//计算等待时间
if(cur.atime < out.etime){
totwait += out.etime - cur.atime;
q.push(node(cur.atime,cur.ptime,out.etime+cur.ptime));//注意结束时间
}else{
q.push(node(cur.atime,cur.ptime,cur.atime+cur.ptime));//注意结束时间
}
q.pop();//记得弹出
idx++;
}
printf("%.1f",totwait/idx/60);
return 0;
}