很難懂的一個題
隊列結構體都可以解決
但邊緣數據有點惡心哦
具體思想:從頭便利隊列(外層循環),便利各個窗口(內層),標志變量控制是否需要等待時長,多個數組來存儲各種數據
ps:代碼來源網絡,自己稍作修改,對邊緣數據做了處理(by:琪)
假設銀行有K個窗口提供服務,窗口前設一條黃線,所有顧客按到達時間在黃線后排成一條長龍。當有窗口空閑時,下一位顧客即去該窗口處理事務。當有多個窗口可選擇時,假設顧客總是選擇編號最小的窗口。
本題要求輸出前來等待服務的N位顧客的平均等待時間、最長等待時間、最后完成時間,並且統計每個窗口服務了多少名顧客。
輸入格式:
輸入第1行給出正整數N(≤1000),為顧客總人數;隨后N行,每行給出一位顧客的到達時間T和事務處理時間P,並且假設輸入數據已經按到達時間先后排好了順序;最后一行給出正整數K(≤10),為開設的營業窗口數。這里假設每位顧客事務被處理的最長時間為60分鍾。
輸出格式:
在第一行中輸出平均等待時間(輸出到小數點后1位)、最長等待時間、最后完成時間,之間用1個空格分隔,行末不能有多余空格。
在第二行中按編號遞增順序輸出每個窗口服務了多少名顧客,數字之間用1個空格分隔,行末不能有多余空格。
輸入樣例:
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
感謝浙江財經大學王瑞洲、周甄陶同學修正測試數據!
作者: DS課程組
單位: 浙江大學
時間限制: 400ms
內存限制: 64MB
結構體做法
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int t, p;//到達時間,處理時間
} ST;
ST q[1005];//數組模擬隊列
int main()
{
int l, r, n, k, i;
scanf("%d",&n);
l = r = 0;//隊列頭和尾
for(i = 0; i < n; i++)
{
scanf("%d %d", &q[r].t, &q[r].p);//將輸入的數入隊列
if(q[r].p > 60) q[r].p = 60;//根據題目要求,最大處理時間60
r++;
}
scanf("%d", &k);//k個窗口
int sumwait = 0, lenwait = 0, wait = 0;//總的等待時間, 最長的等待時間, 單次等待時間
int sum[15] = {0}, winnum[15] = {0};//完成時間,窗口人數
while(l < r)
{
int flag = 0, minn = 99999, imin = 0;//標記變量, 最快的完成時間, 最快完成時間的下標
for(i = 0; i < k; i++)//遍歷k個窗口
{
if(sum[i] <= q[l].t)//如果隊列首位,到達時間比完成時間大,就代表不需要等待
#include<stdlib.h>
typedef struct node
{
int t, p;//到達時間,處理時間
} ST;
ST q[1005];//數組模擬隊列
int main()
{
int l, r, n, k, i;
scanf("%d",&n);
l = r = 0;//隊列頭和尾
for(i = 0; i < n; i++)
{
scanf("%d %d", &q[r].t, &q[r].p);//將輸入的數入隊列
if(q[r].p > 60) q[r].p = 60;//根據題目要求,最大處理時間60
r++;
}
scanf("%d", &k);//k個窗口
int sumwait = 0, lenwait = 0, wait = 0;//總的等待時間, 最長的等待時間, 單次等待時間
int sum[15] = {0}, winnum[15] = {0};//完成時間,窗口人數
while(l < r)
{
int flag = 0, minn = 99999, imin = 0;//標記變量, 最快的完成時間, 最快完成時間的下標
for(i = 0; i < k; i++)//遍歷k個窗口
{
if(sum[i] <= q[l].t)//如果隊列首位,到達時間比完成時間大,就代表不需要等待
/*===== (由於數據做了修改,這里講<改為<=)=======*/
{
sum[i] = q[l].t + q[l].p;//更新完成這個窗口完成的時間
winnum[i]++;//窗口人數加一
flag = 1;//標記一下,代表不需要等待
l++;//隊列首位除去
break;//退出循環
}
if(minn > sum[i])//如果需要等待,就記錄各個窗口里最快完成的那個窗口的完成時間,和下標
{
minn = sum[i];
imin = i;
}
}
if(!flag)//需要等待
{
wait = minn - q[l].t;//等待的時間,最快完成的時間減去隊列第一個人到達的時間
if(lenwait < wait) lenwait = wait;//不斷更新等待的最長時間
sumwait += wait;//求等待時間的和
sum[imin] = minn + q[l].p;//更新對應窗口的完成時間
winnum[imin]++;//對應窗口人數++
l++;//隊列刪除首位
}
}
int last = 0;
for(i = 0; i < k; i++)
{
if(last < sum[i]) last = sum[i];//求最大完成時間
}
printf("%.1lf %d %d\n", 1.0 * sumwait / n, lenwait, last);//輸出,平均等待時間, 最長等待時間, 最后完成時間
for(i = 0; i < k; i++)
{
printf("%d", winnum[i]);//輸出各個窗口的人數
if(i == k - 1) printf("\n");
else printf(" ");
}
return 0;
}
{
sum[i] = q[l].t + q[l].p;//更新完成這個窗口完成的時間
winnum[i]++;//窗口人數加一
flag = 1;//標記一下,代表不需要等待
l++;//隊列首位除去
break;//退出循環
}
if(minn > sum[i])//如果需要等待,就記錄各個窗口里最快完成的那個窗口的完成時間,和下標
{
minn = sum[i];
imin = i;
}
}
if(!flag)//需要等待
{
wait = minn - q[l].t;//等待的時間,最快完成的時間減去隊列第一個人到達的時間
if(lenwait < wait) lenwait = wait;//不斷更新等待的最長時間
sumwait += wait;//求等待時間的和
sum[imin] = minn + q[l].p;//更新對應窗口的完成時間
winnum[imin]++;//對應窗口人數++
l++;//隊列刪除首位
}
}
int last = 0;
for(i = 0; i < k; i++)
{
if(last < sum[i]) last = sum[i];//求最大完成時間
}
printf("%.1lf %d %d\n", 1.0 * sumwait / n, lenwait, last);//輸出,平均等待時間, 最長等待時間, 最后完成時間
for(i = 0; i < k; i++)
{
printf("%d", winnum[i]);//輸出各個窗口的人數
if(i == k - 1) printf("\n");
else printf(" ");
}
return 0;
}
隊列算法【具體數據結構與上個算法大致相同】
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
struct node
{
int t, p;
};
int main()
{
int n;
cin>>n;
queue <node> q;
int i;
for(i = 0; i < n; i++)
{
node tmp;
cin>>tmp.t>>tmp.p;
if(tmp.p > 60) tmp.p = 60;
q.push(tmp);
}
int k;
cin>>k;
int win[15] = {0}, num[15] = {0};
int wait = 0, maxn = 0, sum = 0;
while(!q.empty())
{
int flag = 0;
int minn = 0x3f3f3f3f, imin = 0;(0x3f3f3f3f為無窮大)
for(i = 0; i < k; i++)
{
if(win[i] <= q.front().t)
{
win[i] = q.front().t + q.front().p;
num[i]++;
flag = 1;
q.pop();
break;
}
if(minn > win[i])
{
minn = win[i];
imin = i;
}
}
if(flag == 0)
{
wait = win[imin] - q.front().t;
win[imin] += q.front().p;
if(maxn < wait) maxn = wait;
sum += wait;
num[imin]++;
q.pop();
}
}
int last = win[0];
for(i = 0; i < k; i++)
{
if(win[i] > last) last = win[i];
}
printf("%.1lf %d %d\n", sum * 1.0 / n * 1.0, maxn, last);
for(i = 0; i < k; i++)
{
cout<<num[i];
if(i != k - 1) cout<<" ";
else cout<<endl;
}
return 0;
}
#include <cstdio>
#include <queue>
using namespace std;
struct node
{
int t, p;
};
int main()
{
int n;
cin>>n;
queue <node> q;
int i;
for(i = 0; i < n; i++)
{
node tmp;
cin>>tmp.t>>tmp.p;
if(tmp.p > 60) tmp.p = 60;
q.push(tmp);
}
int k;
cin>>k;
int win[15] = {0}, num[15] = {0};
int wait = 0, maxn = 0, sum = 0;
while(!q.empty())
{
int flag = 0;
int minn = 0x3f3f3f3f, imin = 0;(0x3f3f3f3f為無窮大)
for(i = 0; i < k; i++)
{
if(win[i] <= q.front().t)
{
win[i] = q.front().t + q.front().p;
num[i]++;
flag = 1;
q.pop();
break;
}
if(minn > win[i])
{
minn = win[i];
imin = i;
}
}
if(flag == 0)
{
wait = win[imin] - q.front().t;
win[imin] += q.front().p;
if(maxn < wait) maxn = wait;
sum += wait;
num[imin]++;
q.pop();
}
}
int last = win[0];
for(i = 0; i < k; i++)
{
if(win[i] > last) last = win[i];
}
printf("%.1lf %d %d\n", sum * 1.0 / n * 1.0, maxn, last);
for(i = 0; i < k; i++)
{
cout<<num[i];
if(i != k - 1) cout<<" ";
else cout<<endl;
}
return 0;
}
