(自用随笔)PAT A1014

一道queue的时间模拟题。最后一个样例没过,不想再改了~

思路是,写一个处理函数,每次处理一个顾客,让他的处理时间归零,然后递加当前时间now,把now存入finish数组中。

有几个坑,首先第一遍题目我读错了,只有开始服务时间在17点之后的顾客才会被sorry,而结束时间在17点之后的正常输出。

第二个坑是会出现几个顾客同时处理完毕的情况,大概有2个测试用例。

在写程序的过程中也要注意很多细节,我一开始犯的一个小错误就是,没有把每个顾客的处理时间单独用一个数组存起来,导致最后算开始时间时_time全变为0了。

#include <iostream>
#include <stdio.h>
#include <queue>

using namespace std;

int N,M,K,Q;
int _time[1010];
int timecpy[1010];
int finish[1010];
int now = 480;        //现在时间
int tempnum = 1;      //在黄线外的顾客编号
int finishnumber = 0;     //完成的顾客数
queue<int> window[25];


void Paidui()
{
    int x = M;

    while(x >0)
    {
        for(int k = 1;k<=N;k++)
        {
            window[k].push(tempnum++);
        }
        x--;
    }
}

void Process()
{
    int firstprocesstime = 100000000;       //最先完成的顾客所需时间
    int finishwindow;                   //最先完成的窗口
    for(int l = 1;l<=N;l++)
    {
        int process = _time[window[l].front()];
        //printf("%d\n",window[1].front());
        if(process<firstprocesstime && process >0)
        {
            firstprocesstime = process;
            finishwindow = l;
        }
    }
    now += firstprocesstime;
    //printf("%d\n",now);
    for(int w = 1;w<=N;w++)
    {
        _time[window[w].front()] -= firstprocesstime;          //同步柜台处的处理时间
        if(w != finishwindow && _time[window[w].front()] == 0) //如果有同时结束的,也要处理
        {
            finish[window[w].front()] = now;
            window[w].pop();
            finishnumber++;
        }
    }
    finish[window[finishwindow].front()] = now;
    window[finishwindow].pop();
    finishnumber++;

    if(tempnum<=K)        //将等候区的人插队
    {
        int tempsize = M;
        int minwindow;
        for(int u = 1; u<=N; u++)
        {
            if(window[u].size()<tempsize)
            {
                tempsize = window[u].size();
                minwindow = u;
            }
        }
        window[minwindow].push(tempnum++);
    }
}

int main()
{
    scanf("%d %d %d %d",&N,&M,&K,&Q);

    for(int i = 1;i<=K;i++)
    {
        scanf("%d",&_time[i]);
        timecpy[i] = _time[i];
    }

    Paidui();

    while(finishnumber<K)    //一次处理一个顾客(可能同时处理两个)
    {
        Process();
    }


    for(int j = 1;j<=Q;j++)
    {
        int temp;
        scanf("%d",&temp);
        //printf("%d\n",finish[temp]);
        if((finish[temp] - timecpy[temp]) < 1020)
        {
            printf("%02d:%02d\n",finish[temp]/60,finish[temp]%60);
        }else
        {
            printf("Sorry\n");
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值