• 任务调度(Schedule)


    任务调度(Schedule)


    Description

    A HPS cluster is equipped with a unique task scheduler. To be simple, it is assumed that this cluster doesn’t support multiple tasks running at the same time, such that only one task is allowed to be in running state at any moment. Initially, the priority of ever task is denoted by an integer which is called priority number. The smaller priority number stands for high priority. If two tasks have same task number, the priority is decided in the ASCII order of task name. Following this policy, resources, such as CPU, are always occupied by the task with minimum priority number. When one task is finished, the one with minimum priority number in the rest tasks is picked to execute. The finished task won’t quit immediately. The priority number is doubled and put back to the task set. Once the priority number is greater or equal to 2^32, this task is deleted from the task set.

    Given initial priority setting of every task, your job is to predict the running order of a batch of tasks.

    Input

    First line contains two integers, says n and m. n stands for the number of tasks in initial state. m stands for the length of predicted sequence. Every line is ended by a line break symbol. In each one of the following n lines, an integer and a string are included. This string is shorter than 8, which only contains lowercase letters and numbers. The integer is priority number and the string is the task name. The integer and string is separated by space.

    Output

    At most m lines, each one contains a string. Output the name of tasks according to the order that tasks are executed. If the number of executed tasks is less than m, then output all the executed tasks.

    Example

    Input

    3 3
    1 hello
    2 world
    10 test
    

    Output

    hello
    hello
    world
    

    Restrictions

    0 <= n <= 4,000,000

    0 <= m <= 2,000,000

    0 < Initial priority number < 2^32

    No tasks have same name

    Time: 2 sec

    Memory: 512 MB

    Hints

    Priority queue

    1. 原理与要点:题意就是非常简单的优先队列的应用,由于没有STL,需要手写一个实现一个小根堆。每次取出堆顶,输出,然后将其优先级数乘以2,如果优先级数小于(2^{32}),则重新入队。直至执行m次取出操作或队为空。
    • 小根堆的原理与要点
      • insert:insert(val)操作向二叉堆中插入一个带有权值val的新节点。直接把这个新节点放在存储二叉堆的数组末尾,然后通过交换的方式向上调整,直至满足堆性质。其时间复杂度为堆的深度,即(O(logn))
      • extract: extract操作把堆顶从二叉堆中移出。把堆顶heap[1]与存储在数组末尾的节点heap[n]交换,然后移除数组末尾节点(令n减小1),最后把堆顶通过交换的方式向下调整,直至满足堆性质。其时间复杂度为堆的深度,即(O(logn))
    1. 遇到的问题:
    2. 时间和空间复杂度:时间复杂度(O((m+n)logn)), 空间复杂度(O(n))
    #include "iostream"
    #include "cstring"
    #include "cmath"
    
    using namespace std;
    const int maxn = 1e7;
    typedef long long ll;
    const int SZ = 1<<20;  //快速io
    struct fastio{
        char inbuf[SZ];
        char outbuf[SZ];
        fastio(){
            setvbuf(stdin,inbuf,_IOFBF,SZ);
            setvbuf(stdout,outbuf,_IOFBF,SZ);
        }
    }io;
    struct node {
        ll val;
        char str[10];
    
        friend bool operator<(node a, node b) {
            if (a.val != b.val)
                return a.val < b.val;
            return strcmp(a.str, b.str) < 0;
        }
    } heap[maxn];
    
    int n = 0;
    
    void up(int p) {
        while (p > 1) {
            if (heap[p] < heap[p / 2]) {
                swap(heap[p], heap[p / 2]);
                p /= 2;
            } else break;
        }
    }
    
    void down(int p) {
        int s = p * 2;
        while (s <= n) {
            if (s < n && heap[s+1] < heap[s]) s++;
            if (heap[s] < heap[p]) {
                swap(heap[p], heap[s]);
                p = s;
                s *= 2;
            } else break;
        }
    }
    
    void extract() {
        heap[1] = heap[n--];
        down(1);
    }
    
    void insert(node val) {
        heap[++n] = val;
        up(n);
    }
    
    
    int main() {
    //    freopen("in.txt", "r", stdin);
        int a, b;
        node x;
        scanf("%d %d", &a, &b);
        ll p = 1;
        for (int i = 0; i < 32; i++) {
            p *= 2;
        }
        for (int i = 0; i < a; i++) {
            scanf("%lld %s", &x.val, x.str);
            insert(x);
        }
        while (b-- && n >= 1) {
            printf("%s
    ", heap[1].str);
            x = heap[1];
            x.val *= 2;
            extract();
            if (x.val < p) {
                insert(x);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    spring中的bean
    在Eclipse上使用Maven
    类加载机制
    jstack简单使用,定位死循环、线程阻塞、死锁等问题
    “心若冰清,天塌不惊”,道家文化原文欣赏,你值得收藏研读!
    【干货分享】可能是东半球最全的.NET Core跨平台微服务学习资源
    Oracle 查询两个时间段内的所有日期列表
    SQL Server中获取指定时间段内的所有月份
    天气预报接口
    pixel和nexus设备安卓9.0/8.1/7.1.x/6.x WiFi和信号图标出现叉x号或者感叹号的消除办 法
  • 原文地址:https://www.cnblogs.com/albert-biu/p/11542109.html
Copyright © 2020-2023  润新知