迅雷面试题: 模拟银行一天的工作, 统计vip客户和普通客户的办理业务的平均等待时间.
需求如下:
某銀行的個人業務采用比較流行的取號叫號方式,該行的個人用戶分為金卡用戶和普通卡用戶.
個人業務窗口也分為金卡窗口和普通卡窗口,金卡窗口有金卡客戶等待叫號時只為金卡用戶服務,
普通卡窗口在有普通卡用戶等待叫號時置為普通卡用戶服務.
??? 假定某銀行對一個儲蓄所做了調查統計,總結出顧客到達的時間間隔在1分鐘到3分鐘之間,
?每個人的業務需要1分鐘到9分鐘.
???? 該儲蓄所設立了2個金卡窗口和2個普通卡窗口.
1) 2007年時金卡用戶于普通卡用戶的比例為3:7. 試模擬一個工作日. 統計金卡用戶和普通卡用戶各自的平均等待時間.
?? (模擬中應該使用隨機數生成函數生成用戶的到來時間和業務時間)
2) 2010年是金卡用戶于普通卡用戶的比例變成了 6:4. 試模擬一個工作日. 統計金卡用戶和普通卡用戶各自的平均等待時間.
3) 設計一種新的工作方式能始終體現出金卡用戶的優勢.
請自定義數據結構
使用C++編程, 可使用STL.
需要寫代碼并且可編譯運行.
?
如果圖掛了, 請訪問如下鏈接下載:http://pan.baidu.com/share/link?shareid=331538&uk=3959729623
#include <stdio.h> #include <stdlib.h> #include <string> #include <arpa/inet.h> #include <sstream> #include <vector> #include <map> #include <list> #include <unistd.h> // for usleepusing namespace std;#ifndef foreach #define foreach(container,it) \for(typeof((container).begin()) it = (container).begin();it!=(container).end();++it) #endif// vip : novip = 3 : 7 bool get_random_is_vip() {return random() % 10 < 3;//return false; }// 下一個客戶到來的間隔時間 int get_next_cs() {return random() % 3 + 1;//return 1; }// 下一個客戶的業務辦理所需時間 int get_random_duration() {return random() % 9 + 1;//return 3; }// 客戶 class CCustomer { public:CCustomer():m_is_vip(false),m_time_duration(0), m_time_in(0){}bool IsVip(){return m_is_vip;}void SetVip(bool is_vip){m_is_vip = is_vip;}// 辦理業務所需時間(不含等待時間)void SetDuration(int duration){m_time_duration = duration;}int GetDuration(){return m_time_duration;}// 到達銀行時間int GetTimeIn(){return m_time_in;}void SetTimeIn(int time_in){m_time_in = time_in;} private:bool m_is_vip;int m_time_duration;int m_time_in; };// 銀行柜臺 class CServicePos { public:CServicePos():m_is_vip(false),m_is_busy(false),m_time_use(0),m_time_duration(0){}bool IsVip(){return m_is_vip;}// 是否正在服務客人bool IsBusy(){return m_is_busy;}// 時間流逝一分鐘void PassOneMin(){m_time_use ++;if (m_time_use > m_time_duration){m_is_busy = false;m_time_use = 0;m_time_duration = 0;}}void SetVip(bool is_vip){m_is_vip = is_vip;}// 受理一個客戶void AcceptOneCs(CCustomer &cs){m_is_busy = true;m_time_use = 1;m_time_duration = cs.GetDuration();}private:bool m_is_vip;bool m_is_busy;int m_time_use;int m_time_duration; };int main() {// 4個柜臺vector<CServicePos> pos_vec;pos_vec.push_back(CServicePos());pos_vec.push_back(CServicePos());pos_vec.push_back(CServicePos());pos_vec.push_back(CServicePos());// 前兩個是vippos_vec[0].SetVip(true);pos_vec[1].SetVip(true);list<CCustomer> cs_list;// 業務辦理完畢的客人數目int vip_done_num = 0;int novip_done_num = 0;// 還未開始辦理的客人數目 (還在排隊中)int vip_wait_num = 0;int novip_wait_num = 0;// 業務辦理完的客戶的總共等待時間int vip_wait_time = 0;int novip_wait_time = 0;int mins_one_day = 8*60;//int mins_one_day = 100;// 下一個客戶將在next_cs分鐘后到達int next_cs = 0;// 時間驅動一天for (int i=0; i<mins_one_day; ++i){// 時間過去1分分鐘, 更新各個柜臺狀態foreach (pos_vec, it){it->PassOneMin();}// 有客人到達if (next_cs == 0){next_cs = get_next_cs();// 隨機生成客戶信息CCustomer cs;cs.SetVip(get_random_is_vip());cs.SetTimeIn(i);cs.SetDuration(get_random_duration());// 加入叫號隊列cs_list.push_back(cs);// 更新等待隊列中的人數if (cs.IsVip())vip_wait_num++;elsenovip_wait_num++;}// 時間過去一分鐘next_cs--;// 檢查每個柜臺, 如果不忙, 則接客foreach (pos_vec, it){if (it->IsBusy())continue;if (vip_wait_num == 0 && novip_wait_num == 0)break;// 當前柜臺是vip柜臺if (it->IsVip()){// 優先服務vipbool find_vip_flag = true;if (vip_wait_num == 0)find_vip_flag = false;foreach (cs_list, it_cs){if (find_vip_flag == it_cs->IsVip()){it->AcceptOneCs(*it_cs);//int wait_time = i - it_cs->GetTimeIn();//printf("wait_time:%d\n", wait_time);if (find_vip_flag){vip_wait_num--;vip_wait_time += (i - it_cs->GetTimeIn());vip_done_num++; // 這里不準確!!}else{novip_wait_num--;novip_wait_time += (i - it_cs->GetTimeIn());novip_done_num++;}cs_list.erase(it_cs);break;}}}// 普通柜臺else{// 優先服務普通客人bool find_vip_flag = false;if (novip_wait_num == 0)find_vip_flag = true;foreach (cs_list, it_cs){if (find_vip_flag == it_cs->IsVip()){it->AcceptOneCs(*it_cs);// 打印下當前客人的等待時間 調試用//int wait_time = i - it_cs->GetTimeIn();//printf("wait_time:%d\n", wait_time);if (find_vip_flag){vip_wait_num--;vip_wait_time += (i - it_cs->GetTimeIn());vip_done_num++; // 這里不準確!!}else{novip_wait_num--;novip_wait_time += (i - it_cs->GetTimeIn());novip_done_num++;}cs_list.erase(it_cs);break;}}}}}// 一天結束時, 打印下最后時刻柜臺的狀態printf("一天結束時, 打印下最后時刻柜臺的狀態\n");printf("pos_vec : \n");int i = 0;foreach (pos_vec, it){printf("index %d , is_busy : %d, is_vip:%d\n", i, it->IsBusy(), it->IsVip());i++;}printf("\n");i = 0;int vip_not_done_num = 0;int novip_not_done_num = 0;int vip_not_done_wait_time = 0;int novip_not_done_wait_time = 0;// 一天結束時, 打印下已經拿了號, 卻沒有等到辦理業務的隊列中的客戶的信息printf("cs_list : \n");foreach (cs_list, it){printf("index: %d , time_in: %d, wait_time: %d, is_vip:%d\n", i, it->GetTimeIn(), mins_one_day-it->GetTimeIn(), it->IsVip());i++;if (it->IsVip()){vip_not_done_num++;vip_not_done_wait_time += (mins_one_day-it->GetTimeIn());}else{novip_not_done_num++;novip_not_done_wait_time += (mins_one_day-it->GetTimeIn());}}// vip & novip 客戶的沒有辦理業務的人數printf("vip & novip 客戶的沒有辦理業務的人數\n");printf("vip_wait_person_num : %d\n", vip_wait_num);printf("novip_wait_person_num : %d\n", novip_wait_num);printf("\n");// vip & novip 客戶的各自的總共等待時間 (只統計沒有辦理業務的客戶)//printf("vip & novip 客戶的各自的總共等待時間 (只統計沒有辦理業務的客戶)\n");//printf("vip_not_done_wait_time : %d\n", vip_not_done_wait_time);//printf("novip_not_done_wait_time : %d\n", novip_not_done_wait_time);//printf("\n");// vip & novip 客戶的各自的平均等待時間 (只統計沒有辦理業務的客戶)//printf("vip_not_done_wait_time(avg) : %d\n", vip_not_done_wait_time/vip_wait_num);//printf("novip_not_done_wait_time(avg) : %d\n", novip_not_done_wait_time/novip_wait_num);//printf("\n");// vip & novip 客戶的成功辦理業務的人數printf("vip & novip 客戶的成功辦理業務的人數\n");printf("vip_done_num : %d\n", vip_done_num);printf("novip_done_num : %d\n", novip_done_num);printf("\n");// vip & novip 客戶的各自的總共等待時間 (只統計已成功辦理業務的客戶)//printf("vip_done_wait_time : %d\n", vip_wait_time);//printf("novip_done_wait_time : %d\n", novip_wait_time);//printf("\n");// vip & novip 客戶的各自的平均等待時間 (只統計已成功辦理業務的客戶)//printf("vip_done_wait_time(avg) : %d\n", vip_wait_time / vip_done_num);//printf("novip_done_wait_time(avg): %d\n", novip_wait_time / novip_done_num);//printf("\n");// vip & novip 客戶的各自的平均等待時間 (沒有辦理業務的客戶也統計在內)printf("vip & novip 客戶的各自的平均等待時間 (沒有辦理業務的客戶也統計在內)\n");printf("vip_wait_time(avg) : %d\n", (vip_wait_time + vip_not_done_wait_time) / (vip_done_num + vip_not_done_num));printf("novip_wait_time(avg): %d\n", (novip_wait_time + novip_not_done_wait_time) / (novip_done_num + novip_not_done_num));printf("\n");return 0; }
默認的輸出如下:
一天結束時, 打印下最后時刻柜臺的狀態
pos_vec :index 0 , is_busy : 1, is_vip:1
index 1 , is_busy : 0, is_vip:1
index 2 , is_busy : 0, is_vip:0
index 3 , is_busy : 0, is_vip:0
cs_list :
vip & novip 客戶的沒有辦理業務的人數
vip_wait_person_num : 0
novip_wait_person_num : 0
vip & novip 客戶的成功辦理業務的人數
vip_done_num : 69
novip_done_num : 169
vip & novip 客戶的各自的平均等待時間 (沒有辦理業務的客戶也統計在內)
vip_wait_time(avg) : 0
novip_wait_time(avg): 0
當vip和非vip比例調整為: 6:4時,輸出如下:
一天結束時, 打印下最后時刻柜臺的狀態
pos_vec :
index 0 , is_busy : 1, is_vip:1
index 1 , is_busy : 0, is_vip:1
index 2 , is_busy : 0, is_vip:0
index 3 , is_busy : 0, is_vip:0
cs_list :
vip & novip 客戶的沒有辦理業務的人數
vip_wait_person_num : 0
novip_wait_person_num : 0
vip & novip 客戶的成功辦理業務的人數
vip_done_num : 133
novip_done_num : 105
vip & novip 客戶的各自的平均等待時間 (沒有辦理業務的客戶也統計在內)
vip_wait_time(avg) : 0
novip_wait_time(avg): 0
==============================
后記, 當時現場做這個題時, 發現無論vip還是非vip的等待時間都是都是 0. 還以為自己的程序出問題了. 面完回來自己做了下, 還是0. 其實想想, 確實應該是0. 為什么呢?
分析如下:
題目中沒隔1~3分鐘來一個客戶, 我們就固定每2分鐘來一個.
題目中每個業務的時間1~9分鐘, 我們就固定5分鐘.
這樣相當于每2分鐘來一個客戶, 辦理時間為5分鐘. 進一步簡化為, 每1分鐘來一個客戶, 辦理時間為2.5分鐘.
這樣子, 銀行只要提供3(3>2.5)個柜臺就可以保證恰好滿足所有客戶都能不用等待的辦理業務. 況且題目中提供了4個柜臺, 肯定綽綽有余了~~.
另外, 我們可進一步來簡化題目來驗證程序的正確性. 把柜臺數減少為1個, 把客戶的到來間隔時間改為1分鐘, 把業務辦理所需時間改為1分鐘, 這樣1個柜臺恰好滿足需求. 如果把業務辦理時間改為2分鐘, 就會產生等待, 并且最終有很多人叫了號并卻沒有機會辦理業務. 通過調整程序的參數證明了這一點.
總結
以上是生活随笔為你收集整理的迅雷面试题: 模拟银行一天的工作, 统计vip客户和普通客户的办理业务的平均等待时间.的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 构造函数中慎用memset
- 下一篇: 6s芯片测试软件,如何简单检测你的苹果使