版权声明:如若转载,请联系作者。 https://blog.csdn.net/liu16659/article/details/88783101
PAT 1014 C++版
1.题意
这是一道模拟题,主要考队列的使用和英语题目的阅读理解。
题意如下:
给出一个银行的排队规则:
01.有N个窗口
02.每个窗口的黄线前有M个位置可供排队服务。超过M个位置之后的人,就需要在外面排队,直到窗口中黄线内的人数减少,然后进入到黄线内。【如果同一时刻有多个黄线内的人数少于M,则对在外面排队的人会就近选择一个窗口号小的进行服务。】
03.前面一个人服务完成之后,则开始对后面的一个人进行服务。
现在给出一个窗口数N,窗口前的容纳人数M,以及待服务的人数K,最后给出一个查询数Q。
2.分析
如何实现这道题呢?其实思想很简单,如下:
01.首先用N个队列模拟N个银行窗口。
02.每个队列的容量都是M,表示【黄线内的最大的可容纳人数】
03.对队首元素进行服务,队首完成之后,比较每个队列的完成时间,选择一个最小的完成时间的队列,然后删除其队首,接着在尾部插入下一个用户。
04.重复步骤1,2,3
05.当所有的用户都已经被安排之后,进行一个循环,计算出每个队列中用户的完成时间。
3.代码
#include<cstdio>
#include<queue>
#include<iostream>
#define maxn 1005
#define winMaxn 25
using namespace std;
int N,M,K,Q;
//有N个窗口 => 队列有N个
queue<int> que[winMaxn];
//将分钟格式化输出为 小时:分钟
void printRes(int totalMin){
int min = totalMin % 60;
int hour = totalMin / 60;
printf("%02d:%02d\n",hour+8,min);
}
//初始化队列
void initQue() {
int i,j;
int start = 1;
for(j = 1;j<= M;j++){ //黄线内的人数
start = (j-1) * N + 1;
for(i = 1;i<= N;i++ ){
que[i].push(start);
start++;
}
}
}
int main(){
cin >> N >> M >> K >> Q;
int i,j;
int time[maxn];//表示每个人的需求时间
int comp[maxn];//表示对K个人的处理结果
int query[maxn];//表示查询的序列
int curWindow[N+1] = {0};//表示当前窗口的时间
//输入每个人的处理时间
for(i=1;i<=K;i++){
cin >> time[i];
}
for(i = 1;i<=Q;i++) { //输入需要查询的人
cin >> query[i];
}
//首先对队列进行初始化处理
initQue();
//对剩下未入队的人进行轮流处理
//下标从1 开始 【不是从1开始,因为已经初始化过了】 ,故开始的下标是 N*M+1
for(i = N*M+1 ; i <= K;i++){
//cout <<"当前正在判断的人是:"<<i<<"\n";
int minWindow = -1;//最小时间所对应的窗口
int minTime = 0x3fffffff;//所有窗口中,最小的时间
for( j = 1; j <= N;j++){ //从1号窗口开始
// cout <<"队首的人是:"<< que[j].front()<<"\n";
int tempTime = ( curWindow[j] + time[que[j].front()] );
if(minTime > tempTime ){//如果当前窗口的时间小于minTime,则选择更新minTime,并且更新minWindow
minWindow = j;
minTime = tempTime ;
}
// cout <<"minTime = "<<minTime<<"\n";
}
//cout <<"这次出队的是:"<< que[minWindow].front() <<"\n";
curWindow[minWindow] += time[que[minWindow].front()];
comp[que[minWindow].front()] = curWindow[minWindow];//写入完成的时间
que[minWindow].pop();//将minWindow号窗口的第一个人出队
que[minWindow].push(i);//入i
}
//对黄线内的M 个人开始服务
for(i = 1;i<=N;i++){
while(!que[i].empty()){
curWindow[i] += time[que[i].front()];
comp[que[i].front()] = curWindow[i];//写入完成的时间
que[i].pop();//将队首元素出队
}
}
for(i = 1;i<=Q;i++){
int startTime = comp[query[i]] - time[query[i]];//表示顾客的开始处理时间
if(startTime >= 540) cout <<"Sorry\n";
else printRes(comp[query[i]]);
}
}
4.测试用例
2 2 7 5
1 2 6 4 3 534 2
3 4 5 6 7
2 2 4 4
1 2 6 4
1 2 3 4
1 2 4 4
1 2 6 4
1 2 3 4
1 2 4 4
1 2 597 4
1 2 3 4
3 2 4 4
1 2 540 4
1 2 3 4
5.坑点
这里的坑点主要有:
5.1 题意的理解
Note that since the bank is closed everyday after 17:00, for those customers who cannot be served before 17:00, you must output Sorry instead.
这句话的意思是:
如果对于不能在17:00之前处理的顾客,将会输出Sorry。那么意思就是对于在17:00之前处理,但是服务时间超过了17:00的顾客,还是应该服务到底的,对应在程序中就应该输出一个时间。
5.2 如何实现一个二维队列
见我的博文链接:C++中如何创建一个二维的队列?