AlenaNuna

导航

华为机试0828||参加博览会

第三题

题目:参加博览会

有n场编号从0到n−1的博览会将要举办,编号为i的的博览会举办时间为[starti,endi],即从第starti天到第endi天,包含第starti天和第endi天。

小明计划参加这些博览会,每天最多可以参加k场博览会。请问小明最多可以参加多少场博览会。需注意,小明不需要全程参加一场博览会,只需要在某一天参加即可。

输入描述

第一行输入包含两个整数n和k,n表示博览会的数量,k表示每天最多可以参加的博览会的数量,1≤n≤10^4,1≤k≤10。

以下n行每行包含两个整数start和end,表示第i场博览会的举办时间,1≤starti≤endi≤10^9。

输出描述

小明最多能参加的博览会数量。

样例输入一

3 1 1 2 2 3 1 1

样例输出一

3

说明

小明每天可以参加1场博览会,那么他可以在第1天参加第三场博览会,第2天参加第一场博览会,第3天参加第二场博览会,因此最多可以参加3场博览会。

样例输入二

5 2 1 1 2 2 1 2 2 2 1 1

样例输出二

4

说明

小明每天可以参加2场博览会,那么他可以在第1天参加第一场博览会和第五场博览会,第2天参加第二场博览会和第三场博览会,因此最多可以参加4场博览会。



题解:

一、题目分析
  1. 问题目标是在给定的若干场博览会中,确定小塔在每天最多参加 k 场博览会的限制下,最多能参加的博览会数量。
  2. 博览会的时间区间为 [start_i, end_i],小塔只需要在某一天参加即可,不需要全程参加一场博览会。
二、思路阐述
  1. 数据存储与排序
    • 首先,使用 pair<int, int> 类型的 vector 来存储博览会的开始时间和结束时间。
    • 然后,按照博览会的开始时间对这些区间进行升序排序,这样可以方便后续的处理。排序函数 cmp 通过比较两个 pair 的第一个元素(开始时间)来确定顺序。
  2. 算法核心步骤
    • 定义一个变量 time_ 表示当前时间,初始值为 0。
    • 使用一个小根堆(优先队列 pri)来存储博览会的结束时间。小根堆可以方便地获取最早结束的博览会。
    • 定义一个变量 idx 表示当前正在处理的博览会的索引,初始值为 1。
    • 定义一个变量 ans 来统计小塔参加的博览会数量,初始值为 0。
  3. 处理过程
    • 进入一个循环,循环条件为 idx <= n(还有未处理的博览会)或者小根堆不为空。
    • 在循环内部,首先处理小根堆中已经结束的博览会,即如果小根堆的顶部元素(最早结束的博览会时间)小于当前时间 time_,则将其从堆中弹出。
    • 接着,检查当前时间 time_ 与下一个博览会的开始时间。如果下一个博览会的开始时间小于等于当前时间,将其结束时间加入小根堆,并递增索引 idx
    • 然后,尝试让小塔参加博览会。对于每天最多参加 k 场的限制,进行 k 次循环。如果小根堆不为空,小塔参加一场博览会,将小根堆顶部元素弹出,同时增加 ans。如果小根堆为空,则无法再参加博览会,跳出这个循环。
    • 最后,更新当前时间 time_。如果小根堆为空,将时间设置为下一个博览会的开始时间;否则,将时间加一。
  4. 输出结果
    • 循环结束后,输出小塔最多能参加的博览会数量 ans
 
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,k;
 4 bool cmp(const pair<int,int>&a,const pair<int,int>&b){
 5     return a.first<b.first;
 6 }
 7 void Work(const vector<pair<int,int>>&a){
 8     int time_=0;
 9     priority_queue<int,vector<int>,greater<int> >pri;
10     int idx=1,ans=0;
11     while(idx<=n||!pri.empty()){
12         while(!pri.empty()&&pri.top()<time_)pri.pop();
13         while(idx<=n&&a[idx].first<=time_){
14             pri.push(a[idx].second);
15             idx++;
16         }
17         for(int i=1;i<=k;i++){
18             if(!pri.empty()){
19                 ans++;
20                 pri.pop();
21             }
22             else break;
23         }
24         if(pri.empty())time_=a[idx].first;
25         else time_++;
26     }
27     cout<<ans;
28 }
29 int main(){
30     ios_base::sync_with_stdio(false);
31     cin.tie(NULL); 
32     cin>>n>>k;
33     vector<pair<int,int>>a(n+1);
34     for(int i=1;i<=n;i++){
35         int s,e;
36         cin>>s>>e;
37         a[i]=make_pair(s,e);
38     }
39     sort(a.begin(),a.end(),cmp);
40     Work(a);
41 }

by:AlenaNuna

posted on 2024-09-09 22:11  AlenaNuna  阅读(67)  评论(0编辑  收藏  举报