1014 Waiting in Line (30分)

/这道题我有很多话想说,首先它考的数据结构就是队列,但是考的非常灵活,光知道队列的实现并不是这道题难的地方,每个窗口就是一个队列,由于窗口之间的时间联系,队列的进出队是相互靠时间制约的,一个队列的队首元素出队会直接影响其他队列队首元素的值。这里我想到陈姥姥在讲图的时候提过其实实际做题过程中并非一定要把图的所有元素装进一个结构体中才叫图,这只是一种形式,队列也是一样,关键的是队列先进先出的模式或者说概念,运用了这种概念就是在用队列,不必拘泥于书上的格式。用比较装的话就是说要重意而不重形。所以这题我就没有特地做出队列,只是用了先进先出的思路。
大概思路就是:把窗口前的整体装在一个MN的二维数组中,在每个窗口前的第一个人中找出用时最短的那个人,让他出队,同时其他队的第一个人时间就相应减这么多,然后出队的这一队再补上一个人,依次循环直到没人再补了。
有以下几点要注意:
1.要设置一个变量t来记录消逝的时间,所谓消逝的时间就是出队人所用时间的累加和
2.要设置一个数组来装每个人开始在窗口办理业务的时间(简称开始办理时间),这个时间就是消逝的时间t加上他所在队列前面所有人花费的时间的总和
3.不管这个人来不来得及办理业务,都要算出他的开始办理时间
4.最后是一个细节问题,就是你找出的窗口前最小时间人可能有人时间跟他一样,但是选窗口编号最小的那个(这个很简单),然后各队列队首减去这个最小时间后就可能等于0,放那就行了不用管,0分钟也是时间,但绝不可能有负数,因为是最小时间,最最关键的是减的时候一定要先用一个变量来装这个最小时间人的时间再去减,不要直接减,否则最小时间人的时间减自己后等于零,比他所在队列序号要大的队列减的就是0而不是这个最小时间了,一定要记住这一点!(因为我就是直接减然后整整一下午没想通,最后还是通过调试一步一步调试出来的,调试是真的牛
,调试大概是我做这题最大的收获)*/
上AC代码:
#include<stdio.h>
#define Max 1001//顾客最大量
int Line[21][11];//黄线内容量,20行10列
int Cus[Max];//下标表示顾客顺序,内容表示要花几分钟
int Quest[Max];//装提问顾客的序号
int N,M,K,Q;//窗口数、队伍最大长度、顾客数、提问数
int ServeTime[Max];//每个顾客服务结束的时间
int searchMin(){//找最小值操作,返回时间最小值的顾客队列号码
int i,v=1;
for(i=1;i<=N;i++)
if(Line[i][1]<Line[v][1])v=i;
return v;
}
void insert(int v,int z){//插入操作
int i,j;
j=Line[v][1];//一定要设置这个临时变量,不然自己把自己减掉后,后面的第一个顾客值不会变 ,这困扰了我整整一个下午
for(i=1;i<=N;i++)//其他窗口第一个顾客时间减少
Line[i][1]-=j;
for(i=2;i<=M;i++)//第v个窗口队伍依次往前移一位,第k个顾客插入队尾
Line[v][i-1]=Line[v][i];
Line[v][M]=z;
}
int main(){
//接受数据
int i,j,k,l;
scanf("%d %d %d %d",&N,&M,&K,&Q);
for(i=1;i<=K;i++)
scanf("%d",&Cus[i]);
for(i=0;i<Q;i++)
scanf("%d",&Quest[i]);
//处理
//先把黄线内排满
k=1;
for(i=1;i<=M;i++)//长度
for(j=1;j<=N;j++){//窗口
if(k<=K){//如果要插入顾客数不大于总顾客数,则执行插入
Line[j][i]=Cus[k];
ServeTime[k]=0;
for(l=1;l<i;l++)
ServeTime[k]+=Line[j][l];
}
k++;
}
//如果黄线内够就不用管了,否则按照办理时间的顺序依次插入顾客
//整个过程中要记录每位顾客什么时候结束办理服务,如果超限则是sorry
int t=0;//时间标志,表示随着时间的流逝队伍的变化
int v;//表示用时最少的正在处理的顾客
while(k<=K){
v=searchMin();//找到窗口前最先完成的队列
t+=Line[v][1];
insert(v,Cus[k]);
ServeTime[k]=t;
for(i=1;i<M;i++)//第k个顾客服务结束的时间
ServeTime[k]+=Line[v][i];
k++;
}
for(i=0;i<Q;i++){
if(ServeTime[Quest[i]]<540)
printf("%02d:%02d\n",(ServeTime[Quest[i]]+Cus[Quest[i]])/60+8,(ServeTime[Quest[i]]+Cus[Quest[i]])%60);
else printf(“Sorry\n”);
}
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值