最大重叠区间数目(及包装笔试题)

有一个party,许多人来参加。一个记录仪记录下了每个人到达的时间 s_i 和离开的时间 e_i ,也就是说每个人在party的时间为 [ s_i, t_i ]。求出这个party 同一时刻最多接纳了多少人。例如:输入 arrl  [] = {1, 2, 9, 5, 5}   exit  [] = {4, 5, 12, 9, 12};输出 3

代码如下:

void findMaxGuests(int arrl[], int exit[], int n)
{
   sort(arrl, arrl+n);
   sort(exit, exit+n);
   int guests_in = 1, max_guests = 1, time = arrl[0];
   int i = 1, j = 0;
   while (i < n && j < n)
   {
      if (arrl[i] <= exit[j])
      {
          guests_in++;
          if (guests_in > max_guests)
          {
              max_guests = guests_in;
              time = arrl[i];  //记录容纳客人最多的时刻
          }
          i++;  
      }
      else 
      {    
          guests_in--;
          j++;
      }
   }
   cout << "Maximum Number of Guests = " << max_guests << " at time " << time;
}

猿辅导笔试题:小猿非常热爱学习,所以他在猿辅导上购买了N节课来提升自己,每节课有一个开始时间S和结束时间E(S和E均用正整数表示)。买完课程后,粗心的小猿发现这些课程之间有些时间冲突,幸好小猿有一种“一心多用”的超能力,能同时兼顾K节课上课。当然是K越大,使用这种能力就越累。请问小猿最少需要一心几用,才能上完所有他买的课程呢? 

代码如下:(另一种解题方法)

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n; cin >> n;
    map<int,int> idx;
    for(int i = 0; i < n; i++){
        int s,e;
        cin >> s >> e;
        idx[s]++;
        idx[e]--;
    }
    vector<int> t;
    for(auto x:idx)
        t.emplace_back(x.second);
    int cur = 0;
    int ans = 0;
    for(int i = 0; i < idx.size(); i++){
        cur += t[i];
        ans = max(ans,cur);
    }
    cout << ans << endl;
    return 0;
}

华为笔试题:自动驾驶出租车订单分配
某城市开展自动驾驶出租车试运营,在城市里面设置了N个固定的,上下客出租车站点,为了方便计算,假设这些站点呈圆形部署。相邻2个站点的行车时间固定为5 ,每个站点内的出租车数目足够多,每辆出租车运行的时候在圆形线路上运行,方向可以顺时针也可以逆时针,选择最短的路线运行,如果起始和终点相同,则为无效订单。不处理。现在有N个乘客使用APP下发订单,包含使用出租车的时间,上车的站点下车的站点,请计算整个运作周期最多有多少辆出租车同时运营。下车时间点的车辆不计算在运行车辆中。
输入:第一行输入N和K , N代表站点的数量, K代表乘客的数目2<=N<=100, 0<=K<=10000,之后K行,分别输入使用车辆的起始时间,上车的站点ID,下车的站点ID,0<=起始时间<= 1000输出最大同时运营的出租车数量。

 这道题本质就是求最大重叠区间数目,和本文最初的问题本质一样,只是用了实际背景包装。首先需要处理输入的数据,确定区间的左右边界,即出租车运作的起始时间和终止时间。题目输入的k行就类似初始问题的k个客人,使用车辆的起始时间t1就是相当于客人入场时间,离场时间是由上车站点ID和下车站点ID计算得到的,由于站点是环形的,每次选择最短路线运行(顺时针和逆时针都可),相邻2个站点的行车时间固定为5。

所以我们判断t2(上车站点)和t3(下车站点)的大小,然后得到车辆终止时间,即相当于客人离场的时间,即

       start[i] = t1;
       if(t2 < t3) {
           end[i] = t1 + min((t3-t2), (n-t3+t2)) * 5;
       } else {
           end[i] = t1 + min((t2-t3), (n-t2+t3)) * 5;
       }

至此,我们确定了每位客人的起始时间和结束时间,调用findMaxGuests函数即可得到最多同时运行的出租车数量。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
   int n, k;
   cin >> n >> k;
   int start[k];
   int end[k];
   int t1, t2, t3;
   for (int i = 0; i < k; i++) {
       cin >> t1 >> t2 >> t3;
       start[i] = t1;
       if(t2 < t3) {
           end[i] = t1 + min((t3-t2), (n-t3+t2)) * 5;
       } else {
           end[i] = t1 + min((t2-t3), (n-t2+t3)) * 5;
       }
   }
   findMaxGuests(start, end, k); //这里的函数就是调用文中第一个代码块中的findMaxGuests()函数
   return 0;
}

 万变不离其宗!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值