第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定

洛谷P1323題:從集合生成到數(shù)字刪除解決刪數(shù)問題

標(biāo)簽:
C++

https://img1.sycdn.imooc.com/e6e26168088c29e313950760.jpg


这道题目实际上包含两个主要部分:1) 按照特定规则生成集合中的前k个最小元素;2) 将这些数字拼接后删除m个数字,使剩余数字最大。我们需要分别解决这两个子问题。

一、集合元素的生成

集合生成规则告诉我们:

  • 1是集合中的元素

  • 如果P在集合中,那么2×P+1和4×P+5也在集合中

为了高效生成前k个最小元素,我们使用了优先队列(最小)数据结构。这种方法确保了每次都能取出当前最小的元素进行处理。

实现细节

  1. 初始化优先队列,放入起始元素1

  2. 循环直到收集到k个元素:

  • 取出堆顶最小元素

  • 检查是否重复(避免同一元素多次处理)

  • 将该元素加入结果集

  • 生成两个新元素(2×P+1和4×P+5)放入优先队列

这种方法的时间复杂度是O(k log k),因为每个元素最多被处理一次,每次堆操作是O(log k)。

二、数字删除策略

将生成的k个数字拼接成一个大数后,我们需要删除m个数字使剩余数字最大。这类似于经典的"删除k位数字使剩余数字最大"问题。

我们采用了单调栈的方法来解决这个问题:

算法思路

  1. 初始化一个空字符串作为结果

  2. 遍历原数字字符串的每个数字:

  • 当还能删除数字(m>0),且当前数字大于结果字符串的最后一个数字时,删除最后一个数字(m减少)

  • 将当前数字加入结果字符串

如果遍历完后还有剩余的删除次数(m>0),从结果字符串末尾删除相应数量的数字

这种方法确保了我们总是删除那些"阻碍"数字变大的数字,时间复杂度是O(n),其中n是数字字符串的长度。

三、完整代码

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

using namespace std;

int main() {
    int k, m;
    cin >> k >> m;
    
    // 使用优先队列(最小堆)来生成集合中最小的k个元素
    priority_queue<int, vector<int>, greater<int>> pq;
    vector<int> elements;
    
    pq.push(1);  // 初始元素1
    
    // 生成前k个元素
    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;
}


四、示例

假设输入k=5, m=2:

  1. 生成前5个元素:1, 3, 5, 7, 9

  2. 拼接成数字字符串:"13579"

  3. 删除2个数字使剩余数字最大:

  • 删除'1'和'3',得到"579"

五、常见问题

  1. 元素重复问题:注意生成的元素可能有重复值,需要跳过处理

  2. 边界条件:当k=1或m=0时的特殊情况

  3. 大数处理:拼接后的数字可能非常大,必须用字符串处理而非数值类型

来源:洛谷题解


點擊查看更多內(nèi)容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評論
感謝您的支持,我會繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學(xué)

大額優(yōu)惠券免費領(lǐng)

立即參與 放棄機會
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號

舉報

0/150
提交
取消