首页 > 试题广场 >

小猿的时间管理

[编程题]小猿的时间管理
  • 热度指数:970 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
小猿非常热爱学习,所以他在猿辅导上购买了N节课来提升自己,每节课有一个开始时间S和结束时间E(S和E均用正整数表示)。买完课程后,粗心的小猿发现这些课程之间有些时间冲突,幸好小猿有一种“一心多用”的超能力,能同时兼顾K节课上课。当然是K越大,使用这种能力就越累。请问小猿最少需要一心几用,才能上完所有他买的课程呢?

输入描述:
第一行输入为N(N ≤ 200000),表示购买课程数。
接下来N行,每行输入两个数Si Ei(0 < Si < Ei < 1e9),为第i节课的起止时间。


输出描述:
请输出最小满足条件的K。
示例1

输入

4
1 4
1 2
2 3
3 4

输出

2
Python版本,复杂度过高,供参考
n = int(input())
a = [[] for i in range(n)]
max_cnt = 0

for i in range(n):
    a[i] = list(map(int, input().split()))

min1 = a[0][0]
max1 = a[0][1]

for i in range(n):
    min1 = min(min1, a[i][0])
    max1 = max(max1, a[i][1])

for i in range(min1, max1+1):
    cnt = 0
    for j in range(n):
        if i >= a[j][0] and i+1 <= a[j][1]:
            cnt += 1
    max_cnt = max(max_cnt, cnt)

print(max_cnt)


发表于 2022-03-22 09:32:28 回复(0)
if __name__ == "__main__":
    N = int(input())
    timeline = dict()
    concurrents = 0
    max_concurrent = 0
    for i in range(N):
        S, E = list(map(int, input().split(" ")))
        if S in timeline:
            timeline[S] += 1
        else:
            timeline[S] = 1
        if E in timeline:
            timeline[E] -= 1
        else:
            timeline[E] = -1
    for t in sorted(timeline):
        concurrents += timeline[t]
        if concurrents > max_concurrent:
            max_concurrent = concurrents
    print(max_concurrent)
既直白又快速。
发表于 2022-03-14 18:09:17 回复(0)
N = int(input())
S, E = [], []
for i in range(N):
    a,b = input().split()
    S.append(int(a))
    E.append(int(b))
j, count, max_len = 0, 0, 0
S.sort()
E.sort()
for i in S:
    while E[j]<= i:
        count -= 1
        j += 1
    count += 1
    max_len = max(max_len, count)
print(max_len)

编辑于 2022-09-17 23:35:26 回复(0)
O(n) 
import java.util.Arrays;
import java.util.Scanner;
 
 
public class Main{
    public static int[] record;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int time = Integer.parseInt(in.nextLine());
        int[] arrive=new int[time];
        int[] leave = new int[time];
        for(int i=0;i<time;i++){
            arrive[i]=in.nextInt();
            leave[i]=in.nextInt();
        }
        Arrays.sort(arrive);
        Arrays.sort(leave);
        int p_ar=0,le=0; int max_len=0;
        while(p_ar<arrive.length&& le<leave.length){
            if(arrive[p_ar]<leave[le]){
                max_len=Math.max(max_len, p_ar-le+1);
                p_ar++;
            }
            else{
                le++;
            }
        }
        System.out.println(max_len);
    }
    
    
}

发表于 2021-04-14 14:41:39 回复(2)
利用map记录变化量 暴力不可过



#include<bits/stdc++.h>

using namespace std;
int main(){
    //freopen("in.dat", "r", stdin);
    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.push_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;

发表于 2021-04-06 11:45:35 回复(3)
遍历每门课窗口的端点,遇到一个起点就增加一个窗口,遇到一个终点就减少一个窗口,这样就可以求得每个时刻窗口的增量。然后遍历每个时间点累加增量,同时求取最大的重叠窗口数。
以题中所给示例为例进行算法的说明:
根据题中所给的四个窗口,我们可以画出如下时间轴,时间坐标下为出现次数,正数表示窗口开始,负数表示窗口关闭。1时刻出现了两次,分别是[1,4]和[1,2]两个窗口的开启;2时刻出现了两次,但一次是[2,3]窗口的开启,一次是[1,2]窗口的关闭,因此合计为0,并没有增加新的窗口;3时刻同理;4时刻均为关闭窗口,因此为-2。
1------------2------------3------------4
2              0               0              -2
最后遍历每个时刻,遇到时刻1,在这个时刻开了两个窗口,从1~2一直是同时开着两个窗口,从2~3也一样,直到最后的4时刻两个窗口都关闭,同时开启的窗口数量2-2=0回归到0。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.TreeMap;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        TreeMap<Integer, Integer> map = new TreeMap<>();
        for(int i = 0; i < n; i++){
            String[] params = br.readLine().split(" ");
            int start = Integer.parseInt(params[0]);
            int end = Integer.parseInt(params[1]);
            map.put(start, map.getOrDefault(start, 0) + 1);
            map.put(end, map.getOrDefault(end, 0) - 1);
        }
        int overLapCount = 0;
        int maxOverLapCount = 0;
        for(int time: map.keySet()){
            overLapCount += map.get(time);
            maxOverLapCount = Math.max(maxOverLapCount, overLapCount);
        }
        System.out.println(maxOverLapCount);
    }
}

发表于 2021-08-18 15:18:06 回复(0)

使用优先队列

#include <bits/stdc++.h>
using namespace std;

int main() {
    int m, a, b;
    cin >> m;
    vector<vector<int>> v(m);
    for (int i = 0; i < m; ++i) {
        cin >> a >> b;
        v[i] = {a, b};
    }
    sort(v.begin(), v.end());
    priority_queue<int, vector<int>, greater<>> pq;
    int ans = 0;
    for (auto& i : v) {
        if (not pq.empty() and pq.top() <= i[0])
            pq.pop();
        pq.push(i[1]);
        ans = max(ans, (int)pq.size());
    }
    cout << ans;
}
发表于 2022-08-06 21:02:39 回复(0)
 
import java.util.HashMap;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

/**
 * @author Fxz
 * @version 1.0
 * @date 2022/8/3 15:15
 */
public class Main {

    static int n;
    static Node[] nodes;
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        nodes = new Node[n + 5];
        HashMap<Integer, Integer> map = new HashMap<>();
        Set<Integer> set = new TreeSet<>();
        for (int i = 0; i < n; i++) {
            int s = sc.nextInt();
            int e = sc.nextInt();
            set.add(s);
            set.add(e);
            nodes[i] = new Node(s, e);
        }

        int cnt = 0;
        for (Integer integer : set) {
            map.put(integer, cnt++);
        }

        int[] arr = new int[set.size() + 5];
        for (int i = 0; i < n; i++) {
            int start = nodes[i].start;
            int end = nodes[i].end;
            Integer index1 = map.get(start);
            Integer index2 = map.get(end);
            arr[index1]++;
            arr[index2]--;
        }

        int max = -1;
        for (int i = 1; i < set.size(); i++) {
            arr[i] += arr[i - 1];
            max = Math.max(arr[i], max);
        }
        System.out.println(max);

    }


    static class Node implements Comparable<Node> {
        int start, end;

        public Node(int start, int end) {
            this.start = start;
            this.end = end;
        }

        @Override
        public int compareTo(Node o) {
            return this.end - o.end;
        }
    }

}

发表于 2022-08-04 15:28:13 回复(0)
import java.util.*;
public class Main {
    // 用的是扫描线技巧
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] start = new int[n];
        int[] end = new int[n];
        for (int i = 0; i < n; i++) {
            start[i] = in.nextInt();
            end[i] = in.nextInt();
        }
        Arrays.sort(start);
        Arrays.sort(end);
        int cnt = 0, max = 0, i = 0, j = 0;
        while (i < n && j < n) {
            if (start[i] < end[j]) { // 扫描到红点
                cnt++;
                i++;
            } else { // 扫描到绿点
                cnt--;
                j++;
            }
            max = Math.max(max, cnt);
        }
        System.out.println(max);
    }
}
发表于 2022-06-30 13:13:15 回复(0)
先针对输入排序。
利用一个优先级队列,将结束时间最早的与当前的开始时间做比较,若能够合并,则合并,表示这段时间不用分心。
合并不了的就需要分心了
import java.util.*;
public class Main {

        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int[][] nums = new int[n][2];

            for (int i = 0; i < n; i++) {
                nums[i][0] = sc.nextInt();
                nums[i][1] = sc.nextInt();
            }

            sc.close();    

            Arrays.sort(nums, (a, b) -> a[0] != b[0] ? a[0] - b[0] : a[1] - b[1]);  
            Queue<int[]> queue = new PriorityQueue<>((a, b) -> a[1] - b[1]);
            queue.offer(nums[0]);

            for (int i = 1; i < n; i++) {
                int[] last = queue.peek();
                if (last[1] <= nums[i][0]) {
                    queue.poll();
                    queue.offer(new int[]{last[0], nums[i][1]});
                } else {
                    queue.offer(nums[i]);
                }
            }

            System.out.println(queue.size());
        }
    }

发表于 2022-03-26 11:34:42 回复(0)

热门推荐

通过挑战的用户

小猿的时间管理