题解 | #密码生成#

密码生成

http://www.nowcoder.com/practice/96bf0c548a094de7a05919e0b32b1a5a

  1. 本题的思路,首先把所有的线段排序,按左边排序,然后每一次对数组进行修改的时候,都把包含这个点的线段添加到优先队列,然后判断优先队列的top线段是否包含这个点,包含直接修改值,不包含直接弹出队列,如果队列没有满足的,那么不修改默认为0,有满足的直接修改。
#include<bits/stdc++.h>
using namespace std;



struct node {
    int l, r, v;
};

bool operator <(node a, node b) {

    return a.v < b.v;//这个是给最大堆用的。(否则最大堆不知道怎么判断,只需要定义同方向)
}

int main() {
    long  N, M;
    cin >> N >> M;
    int  Li, Ri;

    vector<int> pass(N, 0);

    vector<node> tmp;//线段加值放到堆里面
    for (int i = 1; i <= M; i++) {
        cin >> Li >> Ri;

        node now;//准备生成线段

        now.l = Li;
        now.r = Ri;
        now.v = i;

        tmp.push_back(now);
    }

    sort(tmp.begin(), tmp.end(), [](node a, node b) {
        return a.l < b.l;//左端点进行线段的递增序列
        });

    priority_queue<node> q;//构造一个最大堆
    int pos = 0;//线段的下标

    //从第一个角标开始尝试
    for (int i = 0; i < N; i++) {

        while (pos < M && i >= tmp[pos].l ) {//包含这个点的线段都放进去。
            q.push(tmp[pos]);
            pos++;
        }

        //按照堆顶顺序进行赋值(刚好就是那个从下到上的一个尝试)
        while (!q.empty()) {
            node now = q.top();

            if (now.r < i) {//角标超出范围(已经不是那个线断了)(不是这个线段之前已经被处理了)
                q.pop();
            }
            else {
                pass[i] = now.v;//赋值
                break;//因为是最大堆,赋值一次,弹出(剩下的还有可能子啊下一个元素用)
            }

        }


    }


    long long sum = 0;
    for (long i = 0; i < N; i++) {
        sum += i * pass[i];
        sum = sum % 100000009;

    }
    cout << sum<< endl;

    return 0;
}
大厂笔试题题解 文章被收录于专栏

主要是公司笔试题得一些总结

全部评论

相关推荐

点赞 评论 收藏
分享
点赞 评论 收藏
分享
06-11 17:39
门头沟学院 Java
小呆呆的大鼻涕:卧槽,用户彻底怒了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务