九度-1326-Waiting in Line-模拟题 | Acm之家
有K个客户去银行办理业务,黄线内可以排队M个人。黄线外的人会优先选择人数少的队去排。 每个人花费的时间是不一样的。问每个人业务结束的时间。稍微有些繁琐的模拟。即使是17点之前开始办业务,17点之后仍然没有办完就是sorry。
PAT 1014. Waiting in Line
http://blog.csdn.net/u013027996/article/details/17475331
http://www.hijeffrey.com/pat-advanced-1014-waiting-in-line.html
- Suppose a bank has N windows open for service. There is a yellow line in front of the windows which devides the waiting area into two parts. The rules for the customers to wait in line are:
- The space inside the yellow line in front of each window is enough to contain a line with M customers. Hence when all the N lines are full, all the customers after (and including) the (NM+1)st one will have to wait in a line behind the yellow line.
- Each customer will choose the shortest line to wait in when crossing the yellow line. If there are two or more lines with the same length, the customer will always choose the window with the smallest number.
- Customer[i] will take T[i] minutes to have his/her transaction processed.
- The first N customers are assumed to be served at 8:00am.
For example, suppose that a bank has 2 windows and each window may have 2 custmers waiting inside the yellow line. There are 5 customers waiting with transactions taking 1, 2, 6, 4 and 3 minutes, respectively. At 08:00 in the morning, customer1 is served at window1 while customer2 is served at window2. Customer3 will wait in front of window1 and customer4 will wait in front of window2. Customer5 will wait behind the yellow line.
At 08:01, customer1 is done and customer5 enters the line in front of window1 since that line seems shorter now. Customer2 will leave at 08:02, customer4 at 08:06, customer3 at 08:07, and finally customer5 at 08:10.
- 输入:
- Each input file contains one test case. Each case starts with a line containing 4 positive integers: N (<=20, number of windows), M (<=10, the maximum capacity of each line inside the yellow line), K (<=1000, number of customers), and Q (<=1000, number of customer queries).
The next line contains K positive integers, which are the processing time of the K customers.
The last line contains Q positive integers, which represent the customers who are asking about the time they can have their transactions done. The customers are numbered from 1 to K.
- 输出:
- For each of the Q customers, print in one line the time at which his/her transaction is finished, in the format HH:MM where HH is in [08, 17] and MM is in [00, 59]. Note that since the bank is closed everyday after 17:00, for those customers who cannot be served before 17:00, you must output "Sorry" instead.
- 样例输入:
2 2 7 5 1 2 6 4 3 534 2 3 4 5 6 7
- 样例输出:
08:07 08:06 08:10 17:00 Sorry
有K个客户去银行办理业务,黄线内可以排队M个人。黄线外的人会优先选择人数少的队去排。 每个人花费的时间是不一样的。问每个人业务结束的时间。稍微有些繁琐的模拟。即使是17点之前开始办业务,17点之后仍然没有办完就是sorry。
PAT 1014. Waiting in Line
- typedef struct customer
- {
- int begin;
- int end;
- int trans;
- }Customer;
- Customer c[MAX];
- int main(int argc,char *argv[])
- {
- int n,m,k,q;
- int i,j;
- queue<int> windows[20];
- int now,shut_time;
- int count,to_finish;
- scanf("%d%d%d%d",&n,&m,&k,&q);
- for(i=1;i<=k;i++)
- {
- scanf("%d",&c[i].trans);
- c[i].begin=-1;
- c[i].end=-1;
- }
- now=0;
- shut_time=(17-8)*60;
- count=1;
- for(i=0;i<n&&count<=k;i++)//向N个窗口压入一个顾客,开始时间为零
- { //结束时间为交易时间
- windows[i].push(count);
- c[count].begin=0;
- c[count].end=c[count].trans;
- count++;
- }
- for(i=0;i<m-1&&count<=k;i++)//向N个窗口压入分别M-1个顾客,开始时间
- for(j=0;j<n&&count<=k;j++)//是上一个结束时间,结束时间是开始时间
- { //加上交易时间
- c[count].begin=c[windows[j].back()].end;
- c[count].end=c[count].begin+c[count].trans;
- windows[j].push(count);
- count++;
- }
- while(count<=k&&now<shut_time)//将第N*M+1以及之后
- { //顾客插入最先离开顾客的窗口
- to_finish=0;//其为即将完成交易的顾客的窗口编号
- for(i=1;i<n;i++)
- if(c[windows[i].front()].end<c[windows[to_finish].front()].end)
- to_finish=i;//找到最先完成的窗口号
- now=c[windows[to_finish].front()].end;
- windows[to_finish].pop();
- c[count].begin=c[windows[to_finish].back()].end;
- c[count].end=c[count].begin+c[count].trans;
- windows[to_finish].push(count);
- count++;
- }
- for(i=0;i<q;i++)
- {
- int query;
- scanf("%d",&query);
- if(c[query].end==-1||c[query].begin>=shut_time)//从某个顾客开始
- printf("Sorry\n"); //还没服务就要关门了
- else
- printf("%.2d:%.2d\n",c[query].end/60+8,c[query].end%60);
- }
- return 0;
- }
http://blog.csdn.net/u013027996/article/details/17475331
- int main(){
- while(scanf("%d%d%d%d",&n,&m,&k,&q) != EOF){
- for(i = 1; i < k+1; i++){
- scanf("%d",&taskArr[i]);
- }
- for(i = 0; i < n; i++){
- while(!qu[i].empty()){
- qu[i].pop();
- }
- }
- memset(allTime,0,sizeof(allTime));
- int count = 0;
- for(i = 0; i < m; i++){
- for(j = 0; j < n; j++){
- count++;
- if(count > k){
- break;
- }
- allTime[count] = taskArr[count];
- if(!qu[j].empty()){
- allTime[count] += allTime[qu[j].back()];
- }
- qu[j].push(count);
- }
- if(count > k){
- break;
- }
- }
- while(count < k){
- count++;
- int minTime = allTime[qu[0].front()];
- int groupId = 0;
- for(i = 1; i < n; i++){
- int tempTime = allTime[qu[i].front()];
- if(tempTime < minTime){
- minTime = tempTime;
- groupId = i;
- }
- }
- allTime[count] = taskArr[count];
- if(!qu[groupId].empty()){
- allTime[count] += allTime[qu[groupId].back()];
- }
- qu[groupId].pop();
- qu[groupId].push(count);
- }
- int rank;
- for(i = 0; i < q; i ++){
- scanf("%d",&rank);
- if(allTime[rank] > 540){
- printf("Sorry\n");
- }else{
- printf("%02d:%02d\n",8 + allTime[rank]/60,allTime[rank]%60);
- }
- }
- }
- return 0;
- }
http://www.hijeffrey.com/pat-advanced-1014-waiting-in-line.html
- typedef struct Customer{
- //开始服务的时间,为了后续判断是否在 17:00前进行服务
- int startTime;
- int endTime;
- //服务时间
- int processTime;
- }Customer;
- typedef struct Window{
- int head;
- int tail;
- //最大在黄线内就10人
- int winQueue[WINWAIT];
- //窗口当前服务结束时间
- int endTime;
- }Win;
- int main(int argc, char *argv[]) {
- // freopen("1.txt","r",stdin);
- //定义及初始化
- Customer cus[1010];
- Win win[25];
- int N,M,K,Q;
- int i,j;
- for( i = 0 ; i < 1010 ; i++ ){
- cus[i].startTime = 0;
- cus[i].endTime = 0;
- cus[i].processTime = 0;
- }
- for( i = 0 ; i < 25 ; i++ ){
- win[i].endTime = 0;
- win[i].head = 0;
- win[i].tail = 0;
- }
- //数据录入
- scanf("%d%d%d%d",&N,&M,&K,&Q);
- for( i = 1 ; i <= K ; i++) {
- scanf("%d",&cus[i].processTime);
- }
- //进行处理
- i = 1 ;
- //用 i 表示 排在黄线内的客户 ,
- //用 j 表示 当前的窗口号,从小到大为黄线内的客户服务,注意后面 j 赋值的意义
- for( j = 0 ; i <= N * M && i <= K ; i++, j=(j+1)%N ){
- //当前客户服务的开始时间就是窗口为前一个客户服务的结束时间
- cus[i].startTime = win[j].endTime ;
- //客户服务结束
- cus[i].endTime = win[j].endTime + cus[i].processTime;
- //更新当前窗口服务结束时间以便为下一位服务
- win[j].endTime += cus[i].processTime;
- //对窗口进行入队操作
- win[j].winQueue[win[j].tail] = i ;
- win[j].tail =([win[j].tail +1)%WINWAIT ; //这里也需要取模,不然会越界!
- //坑,一开始考虑是不需要的,如果取模不就覆盖第一个排队的,后来朋友说只是下标到第一个没有覆盖
- //想想也对,也不知道一开始怎么想的。
- }
- //黄线内满之后还有客户需要服务 再计算他们的服务时间
- //从黄线前找出服务时间最早结束的窗口,出队,再把一个黄线后的客户入队
- int minTime;
- int cIndex;
- int pos;
- for( ; i <= K ; i++){
- minTime = INF;
- for( j = 0 ; j < N ; j++ ){
- //排在窗口 j 的第一个客户
- cIndex = win[j].winQueue[ win[j].head ];
- if( cus[cIndex].endTime < minTime ){
- minTime = cus[cIndex].endTime;
- pos = j;
- }
- }
- //找到最早结束的一个窗口
- cus[i].startTime = win[pos].endTime ;
- //客户服务结束
- cus[i].endTime = win[pos].endTime + cus[i].processTime;
- //更新当前窗口服务结束时间以便为下一位服务
- win[pos].endTime += cus[i].processTime;
- //对窗口进行入队操作
- win[pos].head = (win[pos].head+1)%WINWAIT;
- win[pos].winQueue[win[pos].tail] = i ;
- win[pos].tail = (win[pos].tail+1)%WINWAIT;
- }
- //查询输出
- int hour,minutes;
- while(Q--){
- scanf("%d",&j);
- if( cus[j].startTime + 8*60 >= 17*60 ){
- printf("Sorry\n");
- }else{
- hour = (cus[j].endTime + 8*60) / 60;
- minutes = (cus[j].endTime + 8*60) % 60;
- printf("%02d:%02d\n",hour,minutes);
- }
- }
- return 0;
- }