zoukankan      html  css  js  c++  java
  • 一码学程 10284 排队找bug 题解 单调队列 或者 线段树RMQ

    注:只是看到题目,未评测,所以不确定代码正确性,但是算法思路没有问题

    描述

    同学们的bug还真是多啊,orz...
    春节期间大家存下的bug都来找肖老师解决了。
    每个人都有bug,但是肖老师却只有一个啊。怎么办?
    所以肖老师让大家按先来后到的顺序排队,一个一个的给大家解决。
    这不一大早起来,肖老师就等着同学们过来解决bug了。不过肖老师偶尔想知道当前队伍中bug数量最少的是多少bug。
    sos xbug操作表示有一个同学有x个bug,并且过来排队等待肖老师解决。
    ok 操作表示肖老师已经解决了排在队伍最前面同学的所有bug。
    min 操作表示肖老师需要知道当前排队队伍中bug数量最少的是多少bug。

    输入格式

    第一行输入一个正整数n,表示总共有n种操作。
    接下来输入n行,每行一种操作。
    【限制条件】
    1≤n≤10^6
    每个人的bug数量不超过1000000。

    输出格式

    对于每一次min操作,输出当前排队中bug最少的数量。
    如果执行min(或者ok)操作时,当前队伍为空,则输出“So happy!No bug!”。

    样例输入

    7
    sos 6bug
    sos 7bug
    min
    ok
    min
    ok
    min
    

    样例输出

    6bug
    7bug
    So happy!no bug!
    

    这道问题可以用单调队列求解,代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1000100;
    
    /**
    * zifeiy: 单调队列解法
    */
    
    queue<int> normal_que;
    deque<int> min_que;
    int a[maxn], n, cnt = 0;
    string s;
    
    int main() {
        cin >> n;
        while (n --) {
            cin >> s;
            if (s == "sos") {
                scanf("%dbug", &a[cnt]);
                normal_que.push(cnt);
                while (!min_que.empty()) {
                    int u = min_que.back();
                    if (a[u] >= a[cnt]) min_que.pop_back();
                    else break;
                }
                min_que.push_back(cnt);
                cnt ++;
            }
            else if (s == "ok") {
                if (normal_que.empty()) {
                    puts("So happy!No bug!");
                } else {
                    int u = normal_que.front();
                    normal_que.pop();
                    while (!min_que.empty() && min_que.front() <= u) {
                        min_que.pop_front();
                    }
                }
            }
            else {  // "min"
                if (min_que.empty()) {
                    puts("So happy!No bug!");
                } else {
                    cout << a[min_que.front()] << "bug" << endl;
                }
            }
        }
        return 0;
    }
    
    

    也可以转换成求解RMQ问题,我这里使用线段树来实现RMQ:

    #include <bits/stdc++.h>
    using namespace std;
    #define INF (1<<29)
    const int maxn = 1000100;
    
    int minn[maxn<<2], n, m, a;
    vector<int> vec;
    vector<int> queries;    // 0表示sos,1表示min,2表示ok
    char ch[111];
    
    void build(int l, int r, int rt) {
        if (l == r) minn[rt] = vec[l];
        else {
            int mid = (l + r) >> 1;
            build(l, mid, rt<<1);
            build(mid+1, r, rt<<1|1);
            minn[rt] = min(minn[rt<<1], minn[rt<<1|1]);
        }
    }
    
    int query(int L, int R, int l, int r, int rt) {
        if (L <= l && r <= R) return minn[rt];
        int mid = (l + r) >> 1;
        int tmp = INF;
        if (L <= mid) tmp = min(tmp, query(L, R, l, mid, rt<<1));
        if (mid+1 <= R) tmp = min(tmp, query(L, R, mid+1, r, rt<<1|1));
        return tmp;
    }
    
    void test() {
        puts("[test]");
        cout << "n = " << n << endl;
        cout << "min{1,2} = " << query(0, 1, 0, n-1, 1) << endl;
        cout << "min{2,2} = " << query(1, 1, 0, n-1, 1) << endl;
    }
    
    int main() {
        scanf("%d", &m);
        for (int i = 0; i < m; i ++) {
            scanf("%s", ch);
            if (strcmp(ch, "sos") == 0) {
                scanf("%dbug", &a);
                vec.push_back(a);
                queries.push_back(0);
                n ++;
            }
            else if (strcmp(ch, "min") == 0) {
                queries.push_back(1);
            }
            else {
                queries.push_back(2);
            }
        }
        build(0, n-1, 1);
        int L = 0, R = -1;
        // test
        //for (int i = 0; i < m; i ++) {
        //    printf("queries[%d] = %d
    ", i, queries[i]);
        //}
    
        for (int i = 0; i < m; i ++) {
            if (queries[i] == 0) R ++;
            else if (queries[i] == 2) { if (L <= R) L ++; }
            else {  // 1 - min
                // cout << "[ " << L << "," << R << " ] : fuck!" << endl;
                if (L > R) puts("So happy!no bug!");
                else printf("%dbug
    ", query(L, R, 0, n-1, 1));
            }
        }
    
        // test();
    
        return 0;
    }
    
  • 相关阅读:
    正则表达式简介
    SQL 语言类型
    C# 与 SQL Server 的数据类型对应关系
    Visual Studio 各版本下载
    使用 Parallel LINQ 进行数据分页
    操作系统版本
    C# 命名规范
    解决chrome浏览器在win8下没有注册类的问题
    HttpClient的基本使用
    HttpClient介绍
  • 原文地址:https://www.cnblogs.com/zifeiy/p/10955712.html
Copyright © 2011-2022 走看看