这是一道模拟题,模拟题我一直不是很会,对于这类题最主要的是要构造一个非常好的数据结构,能很好地匹配题目中的场景
1、将顾客按时间由先到后顺序排队(同时间的按服务时间由短到长排序)
2、用一个结构体模拟窗口,属性是该窗口对外可提供服务(空闲)的时间点,刚开始全都是8:00
3、对于每一个顾客选择窗口来说,选择那个提供服务时间最早的窗口
代码如下:
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn=10010;
const int maxn_q=110;
struct Serve{
int h;
int m;
int s;
int t;
}serve[maxn];
//这里记录的是队列最早可以提供服务的时间
//每一次排序即可(如果是个优先队列就好了,先这样写,爆了再换)
struct Queue{
int h;
int m;
int s;
}q[maxn_q];
bool cmp(Serve s1,Serve s2){
if(s1.h!=s2.h){
return s1.h<s2.h;
}else if(s1.m!=s2.m){
return s1.m<s2.m;
}else if(s1.s!=s2.s){
return s1.s<s2.s;
}else{
return s1.t<s2.t;
}
}
//从队伍中获得最早可以提供服务的那一个队列号
bool cmp_q(Queue q1,Queue q2){
if(q1.h!=q2.h){
return q1.h<q2.h;
}else if(q1.m!=q2.m){
return q1.m<q2.m;
}else{
return q1.s<q2.s;
}
}
int main(){
int N,K;
scanf("%d%d",&N,&K);
int countN=N;
for(int i=0;i<N;i++){
scanf("%d:%d:%d %d",&serve[i].h,&serve[i].m,&serve[i].s,&serve[i].t);
}
//初始化队伍
for(int i=0;i<K;i++){
q[i].h=8;
q[i].m=0;
q[i].s=0;
}
sort(serve,serve+N,cmp);
int record=0;
int totalTime=0;//以秒为单位进行统计
while(record<N){
//需要从几个排队中找到最早可以给用户提供服务的那个队列
//获得最早可以提供服务的时间
sort(q,q+K,cmp_q);
Queue top_q=q[0];//当前最早可提供服务的队列
Serve top_s=serve[record];//当前要被服务的人来的时间
//先判断该人是否在下班之前到来
//下班后来的就不算他了
if(top_s.h>17||(top_s.h==17&&top_s.m>0)||(top_s.h==17&&top_s.m==0&&top_s.s>0)){
countN=record;
break;
}else{
//计算这俩的时间差额(秒)
//如果这个人来的时间<服务提供的时间,计算等待时间
if(top_q.h>top_s.h||(top_q.h==top_s.h&&top_q.m>top_s.m)||(top_q.h==top_s.h&&top_q.m==top_s.m&&top_q.s>top_s.s)){
//计算等待时间
totalTime+=(top_q.h*3600+top_q.m*60+top_q.s-top_s.h*3600-top_s.m*60-top_s.s);
//计算这个人完成服务的时间赋值给q[0],服务起始点为提供服务的时间
if(top_q.m+top_s.t>=60){
q[0].m=top_q.m+top_s.t-60;
q[0].h++;
}else{
q[0].m=top_q.m+top_s.t;
}
}else{
//如果这个人来的时间>服务提供的时间,等待时间为0
//计算这个人完成服务的时间赋值给q[0],服务起始点为该顾客到来的时间
if(top_s.m+top_s.t>=60){
q[0].s=top_s.s;
q[0].m=top_s.m+top_s.t-60;
q[0].h=top_s.h+1;
}else{
q[0].s=top_s.s;
q[0].m=top_s.m+top_s.t;
q[0].h=top_s.h;
}
}
}
record++;
}
printf("%.1f",totalTime*1.0/(60*countN));
}
上面关于服务窗口的选择,我们是要选择一个提供服务时间早的窗口,因此我们可以采用优先队列来优化,代码如下:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=10010;
const int maxn_q=110;
struct Serve{
int h;
int m;
int s;
int t;
}serve[maxn];
//这里记录的是队列最早可以提供服务的时间
//每一次排序即可(如果是个优先队列就好了,先这样写,爆了再换)
struct Queue{
int h;
int m;
int s;
bool operator < (const Queue &q2) const {
if(h!=q2.h){
return h>q2.h;
}else if(m!=q2.m){
return m>q2.m;
}else{
return s>q2.s;
}
}
};
bool cmp(Serve s1,Serve s2){
if(s1.h!=s2.h){
return s1.h<s2.h;
}else if(s1.m!=s2.m){
return s1.m<s2.m;
}else if(s1.s!=s2.s){
return s1.s<s2.s;
}else{
return s1.t<s2.t;
}
}
//从队伍中获得最早可以提供服务的那一个队列号
bool cmp_q(Queue q1,Queue q2){
if(q1.h!=q2.h){
return q1.h<q2.h;
}else if(q1.m!=q2.m){
return q1.m<q2.m;
}else{
return q1.s<q2.s;
}
}
int main(){
int N,K;
scanf("%d%d",&N,&K);
int countN=N;
for(int i=0;i<N;i++){
scanf("%d:%d:%d %d",&serve[i].h,&serve[i].m,&serve[i].s,&serve[i].t);
}
//初始化队伍
priority_queue<Queue>q;
for(int i=0;i<K;i++){
Queue temp;
temp.h=8;
temp.m=0;
temp.s=0;
q.push(temp);
}
sort(serve,serve+N,cmp);
int record=0;
int totalTime=0;//以秒为单位进行统计
while(record<N){
//需要从几个排队中找到最早可以给用户提供服务的那个队列
//获得最早可以提供服务的时间
//sort(q,q+K,cmp_q);
Queue top_q=q.top();//当前最早可提供服务的队列
Serve top_s=serve[record];//当前要被服务的人来的时间
//先判断该人是否在下班之前到来
//下班后来的就不算他了
if(top_s.h>17||(top_s.h==17&&top_s.m>0)||(top_s.h==17&&top_s.m==0&&top_s.s>0)){
countN=record;
break;
}else{
//计算这俩的时间差额(秒)
//如果这个人来的时间<服务提供的时间,计算等待时间
if(top_q.h>top_s.h||(top_q.h==top_s.h&&top_q.m>top_s.m)||(top_q.h==top_s.h&&top_q.m==top_s.m&&top_q.s>top_s.s)){
//计算等待时间
totalTime+=(top_q.h*3600+top_q.m*60+top_q.s-top_s.h*3600-top_s.m*60-top_s.s);
//计算这个人完成服务的时间赋值给q[0],服务起始点为提供服务的时间
if(top_q.m+top_s.t>=60){
Queue temp;
temp.m=top_q.m+top_s.t-60;
temp.h=top_q.h+1;
temp.s=top_q.s;
q.pop();
q.push(temp);
}else{
Queue temp;
temp.m=top_q.m+top_s.t;
temp.h=top_q.h;
temp.s=top_q.s;
q.pop();
q.push(temp);
}
}else{
//如果这个人来的时间>服务提供的时间,等待时间为0
//计算这个人完成服务的时间赋值给q[0],服务起始点为该顾客到来的时间
if(top_s.m+top_s.t>=60){
Queue temp;
temp.s=top_s.s;
temp.m=top_s.m+top_s.t-60;
temp.h=top_s.h+1;
q.pop();
q.push(temp);
}else{
Queue temp;
temp.s=top_s.s;
temp.m=top_s.m+top_s.t;
temp.h=top_s.h;
q.pop();
q.push(temp);
}
}
}
record++;
}
printf("%.1f",totalTime*1.0/(60*countN));
}