洛谷P1106 删数问题 贪心+双指针

题目描述
键盘输入一个高精度的正整数 � N(不超过 250250 位),去掉其中任意 � k 个数字后剩下的数字按原左右次序将组成一个新的非负整数。编程对给定的 � N 和 � k,寻找一种方案使得剩下的数字组成的新数最小。
输入格式
输入两行正整数。
第一行输入一个高精度的正整数 � n
第二行输入一个正整数 � k,表示需要删除的数字个数。
输出格式
输出一个整数,最后剩下的最小数。
输入输出样例
输入 #1复制
175438 4
输出 #1复制
13

传送门:P1106 删数问题

看了下题解,好像没有用贪心+双指针写的,所以才有了这篇(喜)

这是蒟蒻的第一篇题解:

设N有n位,去掉其中任意k个数字,题目可转化为:在数字先后顺序不变的情况下,在n位中保留(n-k)位。

要使最终得到的数字尽可能小,则应尽可能使它高位处的数字小,使用p1,p2标示查找区间,区间内查找最小值依次作为;

为了保证查找到的数字尽可能小,则查找的区间应尽可能大,设置查找区间左端点p1=1,p2的设置应尽可能靠后,同时也要保证能查找到足够数量的数字(n-k个),故初始设置p2为第n-(n-k)+1,即第k+1位。

举个例子,如果N=190363,k=3,则初始p1=1,使p2=4保留两位来保底,查找第1至4位间的数字,选出最小值作为结果的最高位,显然为第3位0;更新p1=3+1=4,接下来还需查找出两位,故p2后移,更新p2+=1为5,查找第4至5位,最小值为第4位3;更新p1=4+1=5,p2+=1为6,查找第5至6位,最小值为3;查找3次结束,得到033,记得去掉前导0,结果为33;

The end!

#include<stdio.h>
#include<string.h>
int main(){
    char ch[260]={0};
    int key[260]={0};//记录答案
    int k,i,p1,p2,p;
    scanf("%s%d",ch+1,&k);
    int len=strlen(ch+1);
    for(p1=1,p2=k+1,p=0;p<len-k;p++){//一次查找一位
        int temp=9;//temp最终为当前查找区间内的最小值
        for(i=p1;i<=p2;i++){
            if(ch[i]-'0'<temp)temp=ch[i]-'0';            
        }
        key[p]=temp;
        for(i=p1;;i++){
            if(ch[i]-'0'==temp){
                p1=i+1;    
                break;
            }
        }
        p2++;
    }
    int sum=0;
    for(i=0;i<p;i++){
        sum=sum*10+key[i];    
    }
    printf("%d",sum);
    return 0;
}    

猜你喜欢

转载自blog.csdn.net/Cat_ind/article/details/129214405