题解:P1106 删数问题

这边是题目传送门喵!

欢迎在博客园阅读!

题意简述

给定一个不超过 \(250\) 位的正整数 \(n\),要求删去其 \(k\) 个不同数位上的数字后,使得剩下的数字尽可能大。

思路

最直接的考虑:设 \(n\) 的位数为 \(len\),则剩下的数字一定是 \(len-k\) 位数。首先我要最小化他最高位上的数字。

这是第一步的操作。因此不难想到后面的操作将第一步确定的最高位跳过,对后面的数继续删除。

于是很自然地将 \(k\) 看作是一种“货币”,我删除数字需要消耗货币,然而对于每一次都尽可能最小化最高位,因为最高位更小的策略显然是更优的。那么对于相同大小的最高位,优先选择消耗货币较少的,即需要删除数字较少的。

于是我们就获得了此题的贪心策略。其实一道贪心题被看出是贪心了它就是水题了。

代码实现要注意前导零的处理。前导零的具体处理细节详见代码注释。

代码

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
string n;
int k;
bool flag=0; // 记录这个数是不是删得只剩一个 0 了
// 如果删得只剩一个 0 了就要输出 0
int main(){
    ios;
    cin>>n>>k;
    int pos=0,len=n.size();
    int T=len-k;
    while(T--){ // 每次确定一位上的数字
        int x=10,p=pos;
        for(int i=pos;i<=pos+k;i++){
            if((n[i]-'0')<x)x=n[i]-'0',p=i;
        }
        if(x)flag=1;
        if(flag)cout<<x;
        k-=p-pos; // 将 [pos,p] 中间全部删去
        pos=p+1;
    }
    if(!flag)cout<<"0\n"; // 什么都没输出过说明这个数字就是 0
    return 0;
}

感谢阅读!

posted @ 2026-01-20 15:26  Circle_Table  阅读(15)  评论(0)    收藏  举报