思路
1、不需要使用隊(duì)列,但需要用結(jié)構(gòu)體存儲(chǔ)樣本;
2、在結(jié)構(gòu)體中記錄“到達(dá)時(shí)間”和“服務(wù)時(shí)間”,以此為據(jù)計(jì)算等待時(shí)間;
3、如果沒(méi)有vip這一設(shè)定,那打網(wǎng)球的先后與到達(dá)時(shí)間的先后完全相同;
4、但是有vip掛B,將存在插隊(duì)情況;
5、核心算法是“進(jìn)來(lái)一個(gè)找一個(gè)”,即進(jìn)來(lái)一個(gè)人,找他應(yīng)該去的網(wǎng)球場(chǎng),此時(shí)分情況討論。
情況1:球場(chǎng)有閑置,而這個(gè)人不是vip,選擇編號(hào)最小的球場(chǎng);
情況2:球場(chǎng)有閑置,且這個(gè)人是vip,則首先選擇編號(hào)最小的vip球場(chǎng),如果沒(méi)有vip球場(chǎng),就選擇編號(hào)最小的球場(chǎng);
情況3:如果球場(chǎng)全滿就等待,直到某個(gè)(或者多個(gè)同時(shí))球場(chǎng)空出,在等待的過(guò)程中可能還會(huì)有人進(jìn)來(lái),此時(shí)繼續(xù)分情況討論;
情況3-1:在等待的人中無(wú)vip,那么選擇編號(hào)最小的空球場(chǎng);
情況3-2:在等待的人中有vip,但空余球場(chǎng)中無(wú)vip球場(chǎng),那么同情況3-1;
情況3-3:在等待的人中有vip,且空余球場(chǎng)中有vip球場(chǎng),則將最先到達(dá)的vip掛B送進(jìn)vip球場(chǎng);
6、由于vip掛B的存在,必須在結(jié)構(gòu)體中加入visited來(lái)記錄此人是否已經(jīng)進(jìn)入球場(chǎng),特別要注意不僅在進(jìn)入過(guò)程中要檢測(cè)visited,尋找等待的人中是否有vip時(shí)也要檢測(cè)visited;
代碼
#include <stdio.h>
#define max 75600
#define min 28800
typedef struct node1
{
int arrive_time;
int playing_time;
int serve_time;
int isvip;
int visited;
}player;
typedef struct node2
{
struct node1 *p;
int isviptable;
}table;
int cmp(const void *x,const void *y)
{
player *a=(player*)x;
player *b=(player*)y;
return a->arrive_time-b->arrive_time;
}
int find_table(table tables[],int k,int isvip)
{
int i,m=max,flag=-1;
if(isvip==0)
{
for(i=1; i<=k; i++)
{
if(tables[i].p==NULL)return i;
if((tables[i].p->serve_time+tables[i].p->playing_time)<m)
{
m=tables[i].p->serve_time+tables[i].p->playing_time;
flag=i;
}
}
}
else
{
for(i=1; i<=k; i++)
{
if(tables[i].p==NULL&&tables[i].isviptable==1)
{
return i;
}
}
for(i=1; i<=k; i++)
{
if(tables[i].p==NULL)
{
return i;
}
}
for(i=1; i<=k; i++)
{
if((tables[i].p->serve_time+tables[i].p->playing_time)<m)
{
m=tables[i].p->serve_time+tables[i].p->playing_time;
flag=i;
}
}
}
return flag;
}
int FindVipTable(table tables[],int end,int k)
{
int i;
for(i=1;i<=k;i++)
{
if((tables[i].p->serve_time+tables[i].p->playing_time)==end&&
tables[i].isviptable==1)
return i;
}
return -1;
}
int main()
{
int n;
scanf("%d",&n);
player sample[n];
int shi,fen,miao,playing_time;
for(int i=0;i<n;i++)
{
scanf("%d:%d:%d %d %d",&shi,&fen,&miao,&playing_time,&sample[i].isvip);
miao=(shi*60+fen)*60+miao;
sample[i].arrive_time=miao;
sample[i].playing_time=playing_time>120?120*60:playing_time*60;
sample[i].visited=0;
}
qsort(sample,n,sizeof(player),cmp);
int k,m,tem;
scanf("%d %d",&k,&m);
table tables[k+1];
for(int i=1;i<=k;i++)
{
tables[i].p=NULL;
tables[i].isviptable=0;
}
for(int i=0;i<m;i++)
{
scanf("%d",&tem);
tables[tem].isviptable=1;
}
int time,i,j,flag,end,count[101]={0};
for(i=0;i<n;i++)
{
if(sample[i].visited==0)
{
flag=0;
time=sample[i].arrive_time>min?sample[i].arrive_time:min;
if(time>=max)break;
for(j=1; j<=k; j++)
{
if(tables[j].p!=NULL&&(tables[j].p->serve_time+tables[j].p->playing_time)<=time)
tables[j].p=NULL;
}
tem=find_table(tables,k,sample[i].isvip);
if(tem==-1)break;
if(tables[tem].p==NULL)
{
sample[i].serve_time=time;
sample[i].visited=1;
tables[tem].p=&sample[i];
}
else
{
end=tables[tem].p->serve_time+tables[tem].p->playing_time;
if(FindVipTable(tables,end,k)!=-1)
{
for(j=i;sample[j].arrive_time<=end&&j<n; j++)
{
if(sample[j].isvip==1&&sample[j].visited==0)
{
tem=FindVipTable(tables,end,k);
flag=1;
i--;
sample[j].serve_time=end;
sample[j].visited=1;
tables[tem].p=&sample[j];
break;
}
}
}
if(flag==0)
{
sample[i].serve_time=end;
sample[i].visited=1;
tables[tem].p=&sample[i];
}
}
count[tem]++;
j=(flag==0?i:j);
shi=sample[j].arrive_time/3600;
fen=sample[j].arrive_time/60-shi*60;
miao=sample[j].arrive_time%60;
printf("%02d:%02d:%02d ",shi,fen,miao);
time=sample[j].serve_time;
shi=time/3600;
fen=time/60-shi*60;
miao=time%60;
int wait=time-sample[j].arrive_time;
if(wait%60>=30)wait=wait/60+1;
else wait=wait/60;
printf("%02d:%02d:%02d %d\n",shi,fen,miao,wait);
}
}
int sum=0;
for(i=1;i<=k;i++)
{
sum+=count[i];
}
if(sum>0)
{
for(i=1; i<=k; i++)
{
printf("%d%c",count[i],i==k?'\0':' ');
}
}
else printf("\n");
return 0;
}
有問(wèn)題可以留言,歡迎批評(píng)指教;