解題思路:
1、普通客戶到來:從編號最小的窗口開始查看是否有空閑窗口
1)如果有空閑窗口,若此時空閑窗口剛好是VIP窗口,則看一下隊列里面是否有已經到來的VIP客戶,如有,則讓該VIP插隊
2)如果沒有空閑窗口,則尋找最先完成的窗口,若最先完成的窗口也是VIP,同理也要看一下隊列里是否有VIP已經到來,如有,則讓VIP插隊
2、VIP客戶到來:首先查看VIP窗口是否空閑,如空閑,則直接辦理,若不空閑,則尋找最快完成窗口(這里要注意的是:VIP窗口的優先級排在普通窗口之前)
#include <stdio.h> #include <string.h> typedef struct { int t,p,flag; } Queue; Queue Q[1010]; void ChkVip(int start,int end,int sum) { int i,pos; for(i=start; i<end; i++) { if(Q[i].flag==1&&Q[i].t<sum) {//查看是否有VIP客戶已經在等待 pos=i; break; } } if(i<end) {//VIP客戶插隊 Queue tmp=Q[pos]; for(i=pos-1; i>=start; i--) { Q[i+1]=Q[i]; } Q[start]=tmp; } } int main() { int n,i,min; scanf("%d",&n); int front=0,rear=0; for(i=0; i<n; i++) { scanf("%d %d %d",&Q[rear].t,&Q[rear].p,&Q[rear].flag); if(Q[rear].p>60)Q[rear].p=60; rear++; } int k,c; scanf("%d %d",&k,&c); int sum[k],winnum[k]; memset(sum,0,sizeof(sum)); memset(winnum,0,sizeof(winnum)); int SWT=0,WT=0,LWT=0; while(front<rear) { if(Q[front].flag==0) {//隊頭是普通客戶 min=0; for(i=0; i<k; i++) {//查找空閑窗口 if(Q[front].t>=sum[i]) {//此時無需等待 if(i==c)//當前空閑窗口是VIP窗口,則查找此時是否有Vip客戶已經到時來,若vip已經到來,則將vip插隊上來 ChkVip(front,n,sum[i]); sum[i]=Q[front].t+Q[front].p; front++; winnum[i]++; break; } if(sum[i]<sum[min]) min=i; } if(i==k) {//已經到來在等待 if(min==c)//當前空閑窗口是VIP窗口,則查找此時是否有Vip客戶已經到時來,若vip已經到來,則將vip插隊上來 ChkVip(front,n,sum[min]); WT=sum[min]-Q[front].t; if(WT>LWT)LWT=WT; SWT+=WT; sum[min]+=Q[front].p; front++; winnum[min]++; } } else {//隊頭是VIP客戶 if(Q[front].t>=sum[c]) {//查找此時是否有VIP窗口空閑 sum[c]=Q[front].t+Q[front].p; winnum[c]++; front++; } else { min=c; for(i=0; i<k; i++) {//查找最快完成窗口 if(sum[i]<sum[min]) min=i; } if(Q[front].t>=sum[min])//無需等待 sum[min]=Q[front].t+Q[front].p; else {//需等待 WT=sum[min]-Q[front].t; if(WT>LWT)LWT=WT; SWT+=WT; sum[min]+=Q[front].p; } front++; winnum[min]++; } } } int LFT=0; for(i=0; i<k; i++) { if(sum[i]>sum[LFT]) LFT=i; } printf("%.1lf %d %d\n",(double)SWT/n,LWT,sum[LFT]); for(i=0; i<k; i++) { if(i>0) printf(" "); printf("%d",winnum[i]); } return 0; }