1. 程式人生 > >4 銀行排隊問題之單佇列多視窗加VIP服務 (30分)----模擬

4 銀行排隊問題之單佇列多視窗加VIP服務 (30分)----模擬

4 銀行排隊問題之單佇列多視窗加VIP服務   (30分)

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

有些銀行會給VIP客戶以各種優惠服務,例如專門開闢VIP視窗。為了最大限度地利用資源,VIP視窗的服務機制定義為:當佇列中沒有VIP客戶時,該視窗為普通顧客服務;當該視窗空閒並且佇列中有VIP客戶在等待時,排在最前面的VIP客戶享受該視窗的服務。同時,當輪到某VIP客戶出列時,若VIP視窗非空,該客戶可以選擇空閒的普通視窗;否則一定選擇VIP視窗

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

輸入格式:

輸入第1行給出正整數NN\le 10001000),為顧客總人數;隨後NN行,每行給出一位顧客的到達時間T、事務處理時間P和是否VIP的標誌(1是VIP,0則不是),並且假設輸入資料已經按到達時間先後排好了順序;最後一行給出正整數KK\le 1010)—— 為開設的營業視窗數,以及VIP視窗的編號(從0到K-1K1)。這裡假設每位顧客事務被處理的最長時間為60分鐘。

輸出格式:

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

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

輸入樣例:

10
0 20 0
0 20 0
1 68 1
1 12 1
2 15 0
2 10 0
3 15 1
10 12 1
30 15 0
62 5 1
3 1

輸出樣例:

15.1 35 67
4 5 1

題目連結:https://pta.patest.cn/pta/test/4169/exam/4/question/62124

賬號:sdut軟體1501陳衍凱

密碼:5148275

留作備用。

不算是太麻煩的一個模擬,思路還算清晰,寫起來腦子也還沒有混亂。差不多寫了一個小時,天梯賽中可不允許啊,哎,還是太菜了。

不知道為什麼,最後兩組測試死活拿不到。

丟了3分的程式碼:

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
struct node{
    int t,p,v;
    int wait;
    int flag;
}xin[200000];
int num[2000];
int Time[2000];
int vis[2000];
int main(){
    int n;
    scanf("%d",&n);
    int maxn=0;
    for(int i=0;i<=n;i++){
        xin[i].wait=0;
        num[i]=0;
        xin[i].flag=0;
        Time[i]=0;
        vis[i]=0;
    }
    for(int i=1;i<=n;i++){
        scanf("%d%d%d",&xin[i].t,&xin[i].p,&xin[i].v);
        if(xin[i].p>60)
            xin[i].p=60;
        maxn=max(maxn,xin[i].t+xin[i].p);
    }
    int k,m;
    int a[2000];
    int left=0,right=0;
    scanf("%d%d",&k,&m);
    int sum=0;
    for(int i=0;i<=maxn;i++){
        for(int j=1;j<=n;j++){
            if(xin[j].t==i){
                a[right++]=j;
            }
            else if(xin[j].t>i)
                break;
        }
        for(int j=0;j<k;j++){
            if(Time[j]==i){
                vis[j]=0;
            }
        }
        if(!vis[m]){
            for(int j=left;j<right;j++){
                if(xin[a[j]].v==1&&!xin[a[j]].flag){
                    xin[a[j]].flag=1;
                    vis[m]=1;
                    Time[m]=i+xin[a[j]].p;
                    num[m]++;
                    xin[a[j]].wait=i-xin[a[j]].t;
                    break;
                }
            }
        }
        while(left<right){
            int v=a[left];
            if(xin[v].flag){
                left++;
                continue;
            }
            int j;
            for(j=0;j<k;j++){
                if(!vis[j]){
                    break;
                }
            }
            if(j==k)
                break;
            xin[v].wait=i-xin[v].t;
            vis[j]=1;
            num[j]++;
            Time[j]=i+xin[v].p;
            xin[v].flag=1;
            left++;
        }
    }
    int x=0;
    for(int i=1;i<=n;i++){
        sum+=xin[i].wait;
        x=max(x,xin[i].wait);
    }
    printf("%.1lf %d %d\n",sum*1.0/n,x,maxn);
    for(int i=0;i<k;i++){
        printf(i==0?"%d":" %d",num[i]);
    }
    return 0;
}