1 条题解

  • 0
    @ 2025-7-10 15:28:42

    按题意模拟

    #include <bits/stdc++.h>
    using namespace std;
    int n, a[100000 + 5];
    int cnt;                    // 记录有几个栈
    int dd[100000 + 5];         // 每个栈的最底部元素
    stack<int> sta[100000 + 5]; // 右边的栈们
    int now;                    // 已经拿走的盘子的最大值
    int main()
    {
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> a[i];
    
        cnt = 1;
        sta[cnt].push(a[1]);
        dd[cnt] = a[1];
        now = 0; // 右边还没拿过东西,所有比 0 大的都能拿
        for (int i = 2; i <= n; i++)
        {
            if (a[i] < now)
            {
                cout << i - 1;
                return 0;
            }
            // 找到 a[i] 该放在哪个栈上面
            int pos = -1;
            for (int j = 1; j <= cnt; j++)
                if (dd[j] > a[i])
                {
                    pos = j;
                    break;
                }
            // 看看要不要新开一个栈
            if (pos == -1)
            {
                cnt++;
                sta[cnt].push(a[i]);
                dd[cnt] = a[i];
                continue;
            }
            // 把 sta[pos] 的顶端比它小的拿走
            while (sta[pos].top() < a[i])
            {
                now = sta[pos].top();
                sta[pos].pop();
            }
            sta[pos].push(a[i]);
        }
        cout << n;
        return 0;
    }
    
    

    使用二分快速定位应该放的位置

    #include <bits/stdc++.h>
    using namespace std;
    int n, a[100000 + 5];
    int cnt;                    // 记录有几个栈
    int dd[100000 + 5];         // 每个栈的最底部元素
    stack<int> sta[100000 + 5]; // 右边的栈们
    int now;                    // 已经拿走的盘子的最大值
    int main()
    {
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> a[i];
    
        cnt = 1;
        sta[cnt].push(a[1]);
        dd[cnt] = a[1];
        now = 0; // 右边还没拿过东西,所有比 0 大的都能拿
        for (int i = 2; i <= n; i++)
        {
            if (a[i] < now)
            {
                cout << i - 1;
                return 0;
            }
            // 找到 a[i] 该放在哪个栈上面
            int pos = upper_bound(dd + 1, dd + cnt + 1, a[i]) - dd;
            // 看看要不要新开一个栈
            if (pos == cnt + 1)
            {
                cnt++;
                sta[cnt].push(a[i]);
                dd[cnt] = a[i];
                continue;
            }
            // 把 sta[pos] 的顶端比它小的拿走
            while (sta[pos].top() < a[i])
            {
                now = sta[pos].top();
                sta[pos].pop();
            }
            sta[pos].push(a[i]);
        }
        cout << n;
        return 0;
    }
    
    • 1

    信息

    ID
    5977
    时间
    2000ms
    内存
    250MiB
    难度
    3
    标签
    递交数
    6
    已通过
    4
    上传者