PAT甲级 1014 刷题记录


一、答案

(一)推荐答案

链接: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操作产生副本的问题


      最后,萌新写文,如有不足,还望指正

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值