數據結構--隊列--銀行問題


請用順序隊列或鏈式隊列來完成本題。

我們大多都有在銀行排隊的經歷,唉,那坑爹的排隊啊!現在就讓我們來算算我們這些客戶平均需要等多久吧。
每天剛開始時銀行會開m個窗口來為我們total個客戶辦理業務,當有客戶需要辦理業務時,先選擇可以辦理業務的窗口,如果有多個窗口可以辦理業務就選擇空閑時間最長的窗口,如果有多個窗口空閑的時間一樣長,則選擇序號小的窗口辦理業務。假設我們每個人來到的時間和辦理業務所需要的時間(為了簡化問題,采用整數表示時間)都知道了。現在請你算算我們平均需要等待多久呢?

【輸入形式】

有多組測試數據,每組數據開始有兩個正整數m(<20)和total(<200),后面有total對整數,對應客戶先后到來的時間以及辦理業務所需的時間。

【輸出形式】

平均等待的時間,保留兩位小數。

【樣例輸入】

2 6 1 3 4 1 5 3 9 2 13 4 13 3
3 14 0 3 2 2 2 4 5 4 7 2 11 3 12 3 12 4 12 1 13 3 15 4 19 1 22 3 23 2
2 5 0 6 0 5 0 6 7 1 7 2

【樣例輸出】

0.00
0.29
1.20

 

#include<bits/stdc++.h>
using namespace std;
int m,tot,a,b;//全局變量
template<class T> class Pque{
protected:
    struct node{
        T data;
        node* next;
        node():next(NULL){}//以及這里 node.next初始化為NULL 函數體內沒有內容
    };
    node* head;
    int Size;
//protected類型的內容就是一個結構體指針和一個size
public:
    Pque():Size(0){//構造函數 在這里Size初始化為0
        head=new node;//構造函數 head申請了新的節點
    }
    ~Pque(){
        head=head->next;
        while(head) {
            node* t=head;
            head=head->next;
            delete t;
        }
    }
    void push(T t){//插入元素是尾插
        node* p=head;
        for(;p->next&&p->next->data<t;p=p->next);
//最最一開始這個for語句也是不執行的,因為head->next=NULL,直接新建node*n
//這句話還挺重要的哈
//這里不涉及插隊哈 大家過來的,都是從底下t=a+b都是等了的,只是等到你了辦完工的時間比隔壁也是等了辦完公的時間要早,
//所以走的早啊 這是正常的 來得早等了一會辦了一個小時 來的稍稍晚,等了一會,辦一分鍾就完,肯定后者要早出對
//完全不涉及插隊
        node* n=new node;
        n->data=t;n->next=p->next;p->next=n;//這個data存儲的t是辦完一個顧客的業務的時間,就比如你0時開門,8分到,辦一分鍾,data=9
        ++Size;//!!!!!!!!!!!!!!
    }
    T pop(){//隊列啊 出隊只能是隊首元素出隊
        node* p=head->next;
        head->next=p->next;
        T t=p->data;
        delete p;--Size;
        return t;//T是int類型的元素了  返回個這
    }
    T front(){return head->next->data;}
    int size(){return Size;}//用函數是因為size是protected類型的
};

int main(){
    while(cin>>m){//m是窗口數
        Pque<int> win;//這是一個隊列 名字是win
        cin>>tot;//tot總人數
        double wt=0;//waitting time
        for(int i=0;i<tot;++i){
            cin>>a>>b;//a:到達的時間 b:辦理所需時間
            while(win.size()&&win.front()<=a)win.pop();
//這個的意思就是 如果你來的時候 有顧客並且最快辦完業務的顧客的時間在你來到銀行之前
//那么出隊那個最快辦理完業務的 這是個while語句 看看能出隊幾個人 這個語句是把所有早的顧客出隊完
//之后根據銀行剩余顧客情況 1.銀行內顧客數<窗口數 直接進棧辦理業務 2.窗口還是滿的,剩下的打頭的顧客走的時間都比你到的時間晚,那就等,執行else語句
            if(win.size()<m) win.push(a+b);
//最最一開始執行的是這 因為size=0並且head=new head->next=NULL的 所以進棧
//在顧客數<窗口處的時候 永遠是先執行這個if語句不執行上面的for循環
//這個size其實就現在辦公的顧客人數push進去一個 size++ pop出去一個 size--
            else{
                int k=win.front();//前一個最快(!!!因為是head->next->data)辦完工的時間
                wt+=k-a;//你來的早 就得等
                win.pop();//它出棧 隊首出棧
                win.push(k+b);//在k的基礎上+b==你辦完工的時間 這個時間入棧
            }
        }
        cout<<fixed<<setprecision(2)<<wt/tot<<endl;
    }
}

orrrrrrrrrrrrrrrrrrrrrrrrrr

可以先看下面的 理下思路

#include<iostream>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<stdio.h>
#include<malloc.h>
using namespace std;
int main() {
    int m, t;
    while (cin >> m >> t) {  //m:辦理業務的銀行窗口數    t:整個過程辦理業務的人數   這一個while循環完 求出了在一個情形下的情況
        int a, b;   //a:每一個客戶到來的時間 b:該客戶辦理業務的時間
        int sum = 0;//辦理業務等待時間
        int q[20];//窗口數 上限20個
        memset(q,0,sizeof(q));//把該數組所有值先置為0
        for (int i = 0; i < t; i++) {//t客人的數量
            cin >> a >> b;
            int cur = 0;//這個代表窗口 要去選出哪個窗口辦理完上一個業務最快
            int min = q[0];////
            for (int i = 0; i < m; i++) {
                if (q[i] <min) {
                    min = q[i];
                    cur = i;
                }
            }////從min到這 是找出這幾個窗口最小的時間 下一個客戶到哪個窗口去辦理業務

            if (a < q[cur]) { //如果a:到達的時間 比所有的辦理業務結束的時間還要小 那么它就得等  sum就要++了
                sum += (q[cur] - a);//q[cur]:最早結束業務的窗口(eg:24)  a:到來的時間(eg:19) 那么就得等24-19=5分鍾;
                q[cur] += b;//那么這個窗口就又添了一個新業務(在這個窗口等肯定就要在這辦啊) 所以這個窗口結束業務的時間就要再加 +b[上一個人走
                                                                                                   //新客戶立馬辦 不用加排隊的時間哇]
            }
            else { //如果a:到達的時間 比這個q[cur]()小,就是說現在有空余的窗口 那么就直接在這辦理業務了
                q[cur] = a + b;//那么這個空余的窗口就有了新業務 結束業務的時間:a+b(假設上一個人辦完業務是5分走的  8分來了新客人 辦理業務3分鍾
                                                                                                  //所以這個窗口結束業務的時間8+3=11分鍾)
            }

        }
        printf("%.2f\n", sum*1.0/t);//算完啦輸出
    }
    return 0;
}

 


免責聲明!

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



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