7-5 銀行排隊問題之單隊列多窗口服務 (25 分)


題目:

假設銀行有K個窗口提供服務,窗口前設一條黃線,所有顧客按到達時間在黃線后排成一條長龍。當有窗口空閑時,下一位顧客即去該窗口處理事務。當有多個窗口可選擇時,假設顧客總是選擇編號最小的窗口。

本題要求輸出前來等待服務的N位顧客的平均等待時間、最長等待時間、最后完成時間,並且統計每個窗口服務了多少名顧客。

輸入格式:

輸入第1行給出正整數N(≤1000),為顧客總人數;隨后N行,每行給出一位顧客的到達時間T和事務處理時間P,並且假設輸入數據已經按到達時間先后排好了順序;最后一行給出正整數K(≤10),為開設的營業窗口數。這里假設每位顧客事務被處理的最長時間60分鍾。

輸出格式:

在第一行中輸出平均等待時間(輸出到小數點后1位)、最長等待時間、最后完成時間,之間用1個空格分隔,行末不能有多余空格。

在第二行中按編號遞增順序輸出每個窗口服務了多少名顧客,數字之間用1個空格分隔,行末不能有多余空格。

思路:

設兩個結構體分別表示窗口和客戶。每個窗口有他的服務人數和處理完當前客戶后的結束時間。兩重循環每個客戶遍歷所有的窗口,分等待和不等兩種情況討論。

代碼:

#include <iostream>
#include <stdio.h>
#include <malloc.h>
#define inf  -1e9
#define FRE() freopen("in.txt","r",stdin)
using namespace std;
const int maxn = 1010;
struct Windows
{
    int num_people;
    int endTime;
    Windows()
    {
        num_people = 0, endTime = 0;
    }
} w[15];
struct People
{
    int arrive;
    int wait;
    int keep;
} peo[maxn];
int N,K,l,r;

void init()
{
    l = 0,r = 0;
    scanf("%d",&N);
    for(int i = 0; i<N; i++)
    {
        scanf("%d%d",&peo[r].arrive,&peo[r].keep);
        if(peo[r].keep>60)
            peo[r].keep = 60;
        peo[r].wait = 0;
        r++;
    }
    scanf("%d",&K);
    for(int i = 0; i<K; i++)
    {
        w[i].endTime = 0;
        w[i].num_people = 0;
    }
}

void check()
{
    for(int i = 0; i<N; i++)
    {
        printf("%d ",peo[i].keep);
    }
    printf("\n");
}


int main()
{
   // FRE();
    int maxWite = 0,sumWite = 0,lastFinish = 0;
    init();
    while(l<r)
    {
        bool isWait = true;
        int index = -1,minEnd = 1e9;
        for(int i = 0; i<K; i++)
        {
            if(peo[l].arrive>=w[i].endTime)//不需要等待
            {
                w[i].endTime = peo[l].arrive+peo[l].keep;//更新該窗口的結束時間
                w[i].num_people++;//更新該窗口的服務人數
                isWait = false;//標記一下該客戶不需要等待
                break;
            }
            else //需要等待
            {
                if(minEnd > w[i].endTime)//找到結束時間最近的窗口
                {
                    minEnd = w[i].endTime;//更新最近的結束時間
                    index = i;//記錄這個窗口的下標
                }
            }
        }
        if(isWait)
        {
            peo[l].wait += w[index].endTime-peo[l].arrive;//更新客戶的等待時間
            sumWite += w[index].endTime-peo[l].arrive;//求所有客戶的等待時間的總和
            maxWite = max(maxWite, w[index].endTime-peo[l].arrive);//更新最大的等待時間
            w[index].endTime += peo[l].keep;//更新該窗口的結束時間
            w[index].num_people++;//更新該窗口的服務人數
        }
        l++;
    }
    //check();
    for(int i = 0; i<K; i++)
    {
        if(w[i].endTime>lastFinish)
            lastFinish = w[i].endTime;
    }
    printf("%.1f %d %d\n",sumWite*1.0/N, maxWite, lastFinish);
    for(int i = 0; i<K; i++)
    {
        if(i!=0)
            printf(" ");
        printf("%d",w[i].num_people);
    }
    return 0;
}
/*
9
0 20
1 15
1 61
2 10
10 5
10 3
30 18
31 25
31 2
3
*/
/*
6.2 17 61
5 3 1
*/
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM