当前位置:首页 > 洛谷 > 洛谷P1323题解:优先队列与单调栈解决删数问题

洛谷P1323题解:优先队列与单调栈解决删数问题

2个月前 (08-06)

洛谷P1323题解:优先队列与单调栈解决删数问题 洛谷题解 优先队列 最小堆 单调栈 贪心算法 第1张

一、题目解读

洛谷P1323题要求生成前k个最小的元素,并通过删除m个数字使剩余序列单调递增。题目需结合生成算法与优化删除策略,考验对数据结构与贪心思想的运用。

二、解题思路

1. 生成最小k数:利用优先队列最小堆)维护当前最小元素。每次取出队首元素,生成其衍生元素(2x+1和4x+5),避免重复后加入队列,直至得到k个元素。

2. 删除m数优化:将生成的数字拼接为字符串,采用单调栈策略。遍历字符时,若末尾数字小于当前数字且可删除次数剩余,则弹出栈顶直至满足条件,最终保留单调递增子序列

三、解题步骤

1. 输入k和m,初始化优先队列pq(最小堆)并加入初始元素1。

2. 循环k次:

    取出队首元素,若与上一元素重复则跳过。

    加入队列的新元素为2x+1和4x+5,确保队列始终维护最小元素。

3. 将生成的k个元素拼接为字符串numStr。

4. 遍历numStr,利用单调栈删除:

    若当前字符大于栈顶且可删除次数>0,弹出栈顶直至不满足条件。

    将当前字符入栈,最终栈中序列即为删除m个数字后的最大单调递增子串。

5. 若剩余删除次数未用完,从末尾截断字符串。

6. 输出原始序列和优化后的结果。

四、代码与注释

#include <iostream>
#include <queue>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

int main() {
    int k, m;
    cin >> k >> m; // 输入k和m
    
    // 优先队列(最小堆)生成k个最小元素
    priority_queue<int, vector<int>, greater<int>> pq;
    vector<int> elements;
    pq.push(1); // 初始元素1
    
    while(elements.size() < k) {
        int current = pq.top(); // 取出最小元素
        pq.pop();
        // 避免重复元素
        if (!elements.empty() && current == elements.back()) {
            continue;
        }
        elements.push_back(current); // 加入有效元素
        // 生成新元素加入队列
        pq.push(2 * current + 1);
        pq.push(4 * current + 5);
    }
    
    // 拼接数字为字符串
    string numStr;
    for (int num : elements) {
        numStr += to_string(num);
    }
    cout << numStr << endl; // 输出原始序列
    
    // 单调栈删除m个数字优化
    string result;
    int remove = m;
    for (char digit : numStr) {
        // 贪心删除:若当前数字比栈顶大且可删除
        while (remove > 0 &&!result.empty() && digit > result.back()) {
            result.pop_back(); // 弹出栈顶
            remove--;
        }
        result.push_back(digit); // 加入当前数字
    }
    // 剩余删除次数从末尾截断
    if (remove > 0) {
        result = result.substr(0, result.size() - remove);
    }
    cout << result << endl; // 输出优化结果
    return 0;
}

五、总结

该解法巧妙结合优先队列与单调栈:前者高效生成有序序列,后者通过贪心策略删除元素确保单调性。代码简洁且逻辑清晰,避免复杂循环,时间复杂度低。解题时需注意重复元素的判断与删除操作的边界处理,是处理此类生成+优化问题的典型范例。

原创内容 转载请注明出处

分享给朋友:

相关文章

力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

一、题目解读力扣3112题要求解决带时间限制的最短路径问题:给定一个有向图,节点具有消失时间,需计算从起点到各节点的最短路径,且路径总时间不能超过节点的消失时间。题目难点在于需在传统最短路径算法(如D...

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

一、题目解读洛谷P2190题要求解决铁路售票系统中的车厢数量计算问题。题目给定n个车站和m条订票申请,每条申请包含区间[x,y)及乘客数z。需要计算在不超载的情况下(每节车厢最多36人),满足所有乘客...

洛谷P1121题解:动态规划求解环形数组最大子段和问题(附代码注释)

洛谷P1121题解:动态规划求解环形数组最大子段和问题(附代码注释)

一、题目解读洛谷P1121题要求求解环形数组的最大子段和,即在一个环形数组中找到一个连续子段,使其元素和最大。环形数组的特殊性在于首尾元素可相连,需考虑线性子段与跨越首尾的环形子段两种情况。二、解题思...

洛谷P3694题解:动态规划与状态压缩优化解题全解析

洛谷P3694题解:动态规划与状态压缩优化解题全解析

一、题目解读洛谷P3694题要求解决一个多团队人数分配问题,给定n个元素和m个团队,每个元素属于一个团队,需将元素重新排列,使相邻元素属于不同团队,并最小化调整次数。题目难点在于如何高效处理团队间的空...

洛谷P1141题解:迷宫连通块问题的深度优先搜索算法与代码解析

洛谷P1141题解:迷宫连通块问题的深度优先搜索算法与代码解析

一、题目解读洛谷P1141题目要求处理一个由字符构成的迷宫,其中相同字符形成连通块,不同字符构成分隔。题目需统计连通块数量及大小,并支持查询两点是否属于同一连通块。核心在于高效识别并标记迷宫中的连通区...

洛谷P3393题解:基于多源BFS与Dijkstra算法求解图论最小花费路径问题

洛谷P3393题解:基于多源BFS与Dijkstra算法求解图论最小花费路径问题

一、题目解读洛谷P3393题要求在一个包含N个城市和M条双向道路的图中,求解从起点1到终点N的最小花费路径。图中存在僵尸城市(僵尸无法通过)和危险城市(由僵尸城市扩散S步后标记),需要避开所有危险城市...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。