题解 | #跑步训练#

跑步训练

https://ac.nowcoder.com/acm/contest/13215/D

双向链表加hashmap,利用map快速定位出队的第一个人,然后利用链表快速重排表示插队结果。
主要参考LRU算法
时间复杂度:其中map定位是O(1),链表重排也是O(1),每次插队需要寻找插队的最后一个节点,所以O(x)。
欢迎指正!

#include <iostream>
#include <unordered_map>

using namespace std;

struct DLinkedNode {
    int value;
    DLinkedNode* prev;
    DLinkedNode* next;
    DLinkedNode(): value(0), prev(nullptr), next(nullptr) {}
    DLinkedNode(int _value): value(_value), prev(nullptr), next(nullptr) {}
};

class DLinkList {
public:
    unordered_map<int, DLinkedNode*> cache; // map保存每个人的编号到具体节点的映射
    int size;
    DLinkedNode* head;
    DLinkedNode* tail;

    DLinkList(int n);

    void addToHead(DLinkedNode* node) {
        node->prev = head;
        node->next = head->next;
        head->next->prev = node;
        head->next = node;
    }

    void insert(int start, int x);
};

DLinkList::DLinkList(int n){
    head = new DLinkedNode();
    tail = new DLinkedNode();
    head->next = tail;
    tail->prev = head;
    for(int i = n; i >= 1; i--){
        DLinkedNode* node = new DLinkedNode(i);
        cache[i] = node;
        addToHead(node);
    }
}

void DLinkList::insert(int start, int x){
    DLinkedNode* start_node = cache[start];
    DLinkedNode* end_node = start_node;
    while(x > 0 && end_node->next != tail){
        end_node = end_node->next;
        x--;
    }
    start_node->prev->next = end_node->next;
    end_node->next->prev = start_node->prev;
    start_node->prev = head;
    end_node->next = head->next;
    head->next->prev = end_node;
    head->next = start_node;
}

int main(void){
    int n, q;
    cin >> n >> q;
    DLinkList dll(n);
    for(int i = 0; i < q; i++){
        int start, x;;
        cin >> start >> x;
        dll.insert(start, x);
    }
    auto cur = dll.head;
    for(cur = cur->next; cur != dll.tail; cur = cur->next){
        cout << cur->value << " ";
    }
    cout << endl;
    return 0;
}
全部评论

相关推荐

11-08 13:58
门头沟学院 Java
程序员小白条:竟然是蓝桥杯人才doge,还要花钱申领的offer,这么好的公司哪里去找
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务