文章目录
一、答案
(一)推荐答案
链接:PAT甲级1014 测试点4、5
(二)个人解答
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
struct man //个人结构体
{
int id;
int serve_time=0;
int end_time=0;
};
int main()
{
int window_num,window_size,customer_num,query_num;
cin>>window_num>>window_size>>customer_num>>query_num;
vector<man> customer(customer_num); //客户向量,存放客户数据
vector<queue<man>> line(window_num); //窗口队列向量,每一个队列对应一个窗口
queue<man> wait; //等待队列
for(int i=0;i<customer_num;i++){ //读取各顾客等待时间
customer[i].id=i;
cin>>customer[i].serve_time;
}
//前“窗口大小*窗口数量”位的顾客直接进入窗口排队,其余进入等待队列
for(int i=0;i<customer_num;i++){
if(i<window_num*window_size){
if(i<window_num){
customer[i].end_time=customer[i].serve_time;
}
line[i%window_num].push(customer[i]);
}else{
wait.push(customer[i]);
}
}
//伴随各窗口队列顾客离队,为等待队列中的顾客安排窗口,直到没法安排(各窗口第一位顾客完成时间都晚于17:00)
int return_tag=0;
while(return_tag==0 && !wait.empty())
{
int fastest_time=540;
int fastest_win=-1;
//选择首位顾客最早完成的窗口
for(int i=0;i<window_num;i++){
if(line[i].front().end_time<fastest_time){
fastest_time=line[i].front().end_time;
fastest_win=i;
}
}
if(fastest_time==540){ //各窗口第一位顾客完成时间都晚于17:00,没法安排窗口
return_tag=1;
}else{ //安排窗口
line[fastest_win].pop(); //窗口队列首位顾客离队
line[fastest_win].front().end_time=fastest_time+line[fastest_win].front().serve_time;//更新队头顾客完成时间
customer[line[fastest_win].front().id].end_time=line[fastest_win].front().end_time;//同步更新
line[fastest_win].push(wait.front());//等待队列顾客入队
wait.pop(); //已进入窗口,从等待队列离队
}
}
//窗口剩余顾客离队
for(int i=0;i<window_num;i++)
{
while(!line[i].empty()){
if(line[i].front().end_time<540){ //当完成时间早于17:00时,一直安排离队
int save_time=line[i].front().end_time;
line[i].pop();
if(!line[i].empty()){
line[i].front().end_time=save_time+line[i].front().serve_time;
customer[line[i].front().id].end_time=line[i].front().end_time;
}
}else{
break;
}
}
}
//读取需查询的顾客,输出结果
for(int i=0;i<query_num;i++){
int query_cus;
cin>>query_cus;
query_cus=query_cus-1;
int finish_time=customer[query_cus].end_time;
if(finish_time!=0){
int h=finish_time/60+8;
int m=finish_time%60;
printf("%02d:%02d\n",h,m);
}else{
cout<<"Sorry"<<endl;
}
}
return 0;
}
二、坑点
1. 所有业务开始时间早于17:00的顾客都能被服务,哪怕花费9999分钟
2. 优先选择窗口首位顾客最快完成的队伍,哪怕其他队伍总耗时短
三、相关知识
(一)vector 与queue 两种结构的使用方法
这题可以使用简单的整形数组 int [ ] 或 链表与结构体 来完成,但都会比较复杂,使用vector 与queue会是更优解。以下附上两篇链接,可以了解vector 与queue基本使用方法。
1. C++ vector的用法(整理)
2. C++ queue队列 (详细)
(二)其他
同时在写本题过程中还遇到另一个问题:queue中将一个元素入队时是创建了一个新的副本,当队列中的元素修改时,并不会对原元素进行修改,需要自行同步修改。
=> C++ STL的queue中push操作产生副本的问题
最后,萌新写文,如有不足,还望指正