(经典贪心)— 删数问题

B:删数问题

时间限制: C/C++ 1000ms; Java 2000ms 内存限制: 65535KB

通过次数: 3 总提交次数: 6

问题描述

键盘输入一个正整数N,去掉其中任意S个数字后剩下的数字按原左右次序将组成一个新的正整数。编程对给定的N和S,寻找一种方案使得剩下的数字组成的新数最小。(N不超过240位,N > S)

输入描述

两行,第一行:正整数n,第二行:正整数S。

输出描述

  • n去掉的s个数字后组成的新的正整数m。

样例输入

123006
2

样例输出

1006

来源

2016年中北大学新生赛

提示

补充样例
输入
123006 3
输出
6

提交统计讨论

题解:由于数据小顿时变成了水题,暴力。

#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
#include<set>
#include<map>
#include<math.h>
#include<vector>
#include<bitset>
#include<iostream>
#define ullmax 1844674407370955161
#define llmax 9223372036854775807
#define intmax 2147483647
#define re register
#define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1]
using namespace std;
int main(){
    string s;
    int k;
    cin>>s>>k;
    while(k){
        int leap=0;
        for(int i=0;i<s.size()-1;i++){
            if(s[i]>s[i+1]){
                leap=1;
                s.erase(i,1);
                break;
            }
        }
        if(!leap)
            s.erase(s.size()-1,1);
        k--;
    }
    int flag=0;
    for(int i=0;i<s.size();i++){
        if(s[i]=='0'){
            if(flag){
                printf("0");
            }
        }
        else{
            flag=1;
            printf("%c",s[i]);
        }
    }
    printf("\n");
    return 0;
}

1134: 整数去位

时间限制: 1 Sec  内存限制: 128 MB
提交: 962  解决: 175
[提交][状态][讨论版]

题目描述

键盘输入一个高精度的正整数N,去掉其中任意M个数字后剩下的数字按原左右次序将组成一个新的正整数。编程对给定的N和M寻找一种方案使得剩下的数字组成的新数最小。输出组成的新的正整数。
输入数据均不需判错。如果去掉了某几个位后得到的新整数开头为0,保留0。
输入:
505
1
输出:
05

输入

第一行为高精度正整数N(N的长度不超过10^6位)
第二行为M(0<=M<=N的长度)

输出

去掉M位后的最小新数。

样例输入

82386782
3

样例输出

23672

提示

来源

贪心算法★

[提交][状态][讨论版]

题解:数据很大,需要预处理出每个数的后边第一个比其小的数的位置(简称 v),如果 d = v-i 小于 k,意味着可以让更小的数开头,那么其间的数是要被删掉的。

#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
#include<set>
#include<map>
#include<math.h>
#include<vector>
#include<bitset>
#include<iostream>
#define ullmax 1844674407370955161
#define llmax 9223372036854775807
#define intmax 2147483647
#define re register
#define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1]
using namespace std;
int pos[1000005];
int main(){
    string s;
    int k;
    cin>>s>>k;
    int len=s.size();
    pos[len-1]=len;
    for(int i=len-2;i>=0;i--){        //------------------------------
        if(s[i]>s[i+1]){
            pos[i]=i+1;
        }
        else{
            int t=i+1;
            while(t<len&&s[i]<=s[t]){     //  预处理,形式类似 KMP
                t=pos[t];
            }
            pos[i]=t;
        }
    }                                 //--------------------------------
    int i=0;
    while(k){
        int leap=0;
        if(pos[i]-i<=k){
            k-=(pos[i]-i);
            i=pos[i];
            leap=1;
        }
        if(!leap){
            printf("%c",s[i]);
            i++;
        }
    }
    for(int j=i;j<len;j++)
        printf("%c",s[j]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/black_horse2018/article/details/81987092