2023年11月29日-秋招-第一题(100分)-任务分配

在线评测链接

题目描述

塔子哥将对 1 0 5 10^5 105 个通道下发任务。

当用户输入 − 1 -1 1 时,分配没有任务且编号最小的通道给用户。当用户输入有效的通道编号时,回收并清空此通道。

请你计算出若干次操作后,下一次用户申请时将得到的通道编号,若无可以使用的通道,返回 − 1 -1 1

输入格式

第一行为一个整数 n n n,表示用户输入次数。

接下来一行 n n n 个整数,分别表示每一次操作用户的输入数,通道编号在 0 0 0 50000 50000 50000 内。

1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1n105

输出格式

输出下一次将申请到的通道编号,若无可使用的通道,输出 − 1 -1 1

7
-1 -1 1 -1 0 -1 2
2

思路:模拟/小根堆

我们可以使用队列来模拟这个问题,首先把 1 0 5 10^5 105个通道编号全部按顺序入队(通道编号下标从0开始),这样队头元素就是编号最小的通道

  • 用户输出-1,直接弹出队头元素
  • 用户输出为 x x x,则使用二分查找,找到第一个 ≥ x \ge x x的位置,将该位置插入元素 x x x

最终输出的结果即为队列的队头元素

上述模拟的过程,是使用队列+二分查找的思想,也可以直接使用优先队列模拟(Java代码),优先队列是小根堆,这样堆顶就是编号最小的通道

时间复杂度

O ( n l o g n ) O(nlogn) O(nlogn)

代码

C++

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std; 
const int N = 40;
//[1, n],高度不超过 k
int cache[N][N];
int dfs(int n, int k)
{
    if(cache[n][k] != -1) return cache[n][k];
    if(k == 0 && n == 0) return 1;
    if(k == 0 && n != 0)  return 0;
    if(n == 0)  return 1;
    int res = 0;
    for(int i = 1; i <= n; ++ i) {
        res += dfs(i - 1, k - 1) * dfs(n - i, k - 1);
    }
    return cache[n][k] = res;
}
int main()
{
    int n, k;
    cin >> n >> k;
    memset(cache, -1, sizeof cache);
    cout << dfs(n, k) << endl;
    return 0;
}

python代码

import bisect
from collections import deque

n = int(input())
ops = [int(c) for c in input().split()]

q = deque([i for i in range(100000)])

for op in ops:
    if op == -1:
        q.popleft()
    else:
        # 插入op
        bisect.insort(q, op)

if q: print(q[0])
else:
    print(-1)

Java代码

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        PriorityQueue<Integer> q = new PriorityQueue<>();
        for (int i = 0; i < 100000; ++i) {
            q.offer(i);
        }
        for (int i = 0; i < n; ++i) {
            int op = scanner.nextInt();
            if (op == -1) {
                q.poll();
            } else {
                q.offer(op);
            }
        }
        if (!q.isEmpty()) {
            System.out.println(q.peek());
        } else {
            System.out.println(-1);
        }
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

塔子哥学算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值