PTA 队列模拟题目类型总结及解题思路(C++)

1. 队列模拟题目简介

a.题目类型一

  • 一个机构中有N个服务窗口
  • M个顾客到达机构的时间以及每一个顾客须要的服务时间
  • 顾客按照到达的时间前后排队等待服务
  • 求顾客等待时间,顾客开始接受服务的时间,窗口服务人数等

如1014, 1017, 1026, 如下给出1017题目c++

b.题目类型二

  • 给出顾客开启某项服务的时间以及结束该项服务的时间(通常会有冗余数据)
  • 求在指定时间开启该项服务的顾客数,每一个顾客开启服务的总时长

如1006, 1016, 1095,如下给出1016题目windows

c.解题思路

  1. 如何处理输入的数据?数据结构

    • 对于时间输入格式的处理code

      • 时间数据的输入格式通常为MM:dd:HH:mm ,因此能够采用格式化输入的形式读取
      int month, day, hour, min;
      scanf("%d:%d:%d:%d", &month, &day, &hour, &min);
      • 保存时间数据

      通常讲全部的时间转化为读入的最小时间单元,用一个变量保存。在这个例子中,将月、日、小时都转化为分钟的形式。blog

      int time = month*31*24*60+day*24*60+hour*60+min;
    • 建立数据结构保存数据排序

      对于类型一的题目须要建立customer以及window两个结构体队列

      • customer结构中,根据题目要求,通常须要保存顾客到达时间,顾客所需服务时长,顾客开始接受服务的时间等。string

        struct customer{
        	int arrive;
        	int processTime;
        	int start;
        };
      • window结构中,根据题目要求,通常须要保存窗口服务完一个客户后的结束时间,窗口当前服务人数等。it

        struct window{
        	int lastAvailableTime;
        	int count;
        };

      对于类型二的题目通常须要建立info结构体以及一个map用来保存顾客ID与info的关系table

      • info结构体用来保存顾客开启/结束服务的时间以及该时间是开启仍是结束服务;

        struct info{
        	int time;
        	bool isStart;
        }
      • map 结构

        map<string, vector<struct info> > customerInfo;
  2. 如何模拟排队/队列?

    对于类型一的题目

    1. 根据顾客到达的时间前后对全部顾客进行排序

      bool cmp(struct customer a, struct customer b){
          return a.arrive<b.arrive;
      }
      sort(customers.begin(),customers.end(),cmp);
    2. 找到当前最先空闲的窗口

      int index = -1;
      int minEnd = inf;
      for(int j =0;j<windows.size();j++){
        if(windows[j].lastAvailableTime<minEnd){
          minEnd = windows[j].lastAvailableTime;
          index =  j;
        }
      }
    3. 选择该窗口为当前最先到达且还未服务的顾客服务

      • 若是该窗口空闲的时间比顾客到达的时间早

        顾客不须要等待

        窗口下一个空闲时间为顾客到达时间+顾客所须要的服务时间

      • 若是该窗口空闲的时间比顾客到达的时间晚

        顾客需等待

        窗口下一个空闲时间为窗口空闲时间+顾客所须要的服务时间

      if(windows[index].lastAvailableTime>customers[i].arrive){
        totalWait += windows[index].lastAvailableTime-customers[i].arrive;
        windows[index].lastAvailableTime += customers[i].process;
      }
      else{
      	windows[index].lastAvailableTime = customers[i].process+customers[i].arrive;
      }

    对于类型二的题目

    1. 根据题意筛选有效信息,去掉只有开启服务没有结束服务或只有结束服务没有开启服务的信息。

      这里须要针对每个顾客的信息按照时间进行排序,选择对应的开启和结束服务时间

      for(map<string, vector<struct info> >::iterator it = customers.begin();it!=customers.end();it++){
              vector<struct info> vec = it->second;
              sort(vec.begin(),vec.end(),cmp);
              for(int i = 0;i<vec.size()-1;i++){
                  if(vec[i].isOn && vec[i+1].isOn) continue;
                  else if(!vec[i].isOn) continue;
                  else if(vec[i].isOn && !vec[i+1].isOn){
                      /*------to fill-----------*/
                    	/*------根据题意添加--------*/
                      i++;
                  }
              }
          }
    2. 根据筛选出来的信息,按照题意计算。

2. PTA中的队列模拟题

类型一

题号 (按难度排序) 题目难点(各题的不一样) 注意事项
1017(25) 给出窗口数和顾客到达及服务时间 晚与17:00到达的顾客
不接受服务也不计入等待时间
求全部顾客的平均等待时间 注意没有符合要求的顾客时,
须要单独讨论输出0.0
1014(30) 给出窗口数和顾客到达及服务时间 若当前最快的顾客结束时间已达17:00,
把当前全部窗口正在进行的服务处理完即结束
窗口有必定量的排队等待数量 须要改变window的结构体
struct window{
queue<int> customerID;
int lastAvailable = 8*60;};
求每一个顾客离开的时间
1026(30) 给出窗口数和顾客到达及服务时间 21:00:00时再也不接受顾客
规定了VIP窗口和VIP客户,
VIP客户能够优先使用VIP窗口
VIP客户优先使用空闲VIP窗口即便有普通窗口空闲
求顾客开始接受服务和等待服务的时间

类型二

题号(按难度排序) 题目难点(各题的不一样) 注意事项
1006(25) 求最早开启服务的顾客
以及最晚结束服务的顾客
1016(25) 不一样时间段提供服务的收费价格不一样 可能有跨天电话
求每一个顾客每一次服务的花费以及总花费
1095(30) 求总服务时间最长的顾客
求在指定时间开启该项服务的顾客数
相关文章
相关标签/搜索