• 第四章编程总结


    题目:

    给定n位正整数a,去掉其中任意k≤n 个数字后,剩下的数字按原次序排列组成一个新 的正整数。对于给定的n位正整数a和正整数 k,设计一个算法找出剩下数字组成的新数最 小的删数方案。

    输入:

    第 1 行是1 个正整数 a。第 2 行是正整数k

    输出:

    输出最小数。

    输入样例:

    178543

    4

    输出样例:

    13

    题目思路:

    假设我们先只删去一个数,那么我们删了这个数后,这个数的后面一个数就会往前补充我删去的这一位的位置。假设向前补位的数是比我们选择删去的数大,那么结果肯定不是最小值。

    比如:123845.删去3的话:12845,而理想的结果是12345.所以我们要删去大的这个数肯定是比他的后一位大的。这样才能使替补位是小的。

    于是乎,只要从左往右,找到上升序列的末尾元素,即一个小峰值,删去这个数即可。之后继续,删多少位就找多少个峰值。在删一个后找峰值,是从删除后的序列去找的。

    代码:

    #include <bits/stdc++.h>

    using namespace std;

    typedef long long ll;

    string s;

    int k;

    int a[10005];

    int main(){

        string s;

        cin>>s>>k;

        for(int i=0;i<s.size();i++){

            a[i]=s[i]-'0';

        }   

        int len=s.size();

        while(k--){

            for(int i=0;i<len;i++){

                if(a[i]>a[i+1]){

                    for(int j=i;j<len;j++){

                        a[j]=a[j+1];

                    }

                    len--;

                    break;

                }

            }

        }

        int flag=0;

        for(int i=0;i<len;i++){

            if(a[i]!=0){        

                flag=1;         

                cout<<a[i];

            }else if(flag==1){  

                cout<<a[i];

            }

            if(i==len-1 && flag==0){

                cout<<0;

            }       

        }

        return 0;

    }

    注意点:

    有可能删去之后,出现00001000这样的情况,所以,要先判断有没有除零之外的其他数的存在,用flag来标记,如果有,开启输出,如果没有就表明这个数字只要0,那么只需要输出一个0即可。

    算法时间复杂度分析:

    由于删去一个数需要后面的数组往前移,所以一次操作最大位N,最小为0,平均N+0/2 = N/2.如果极端情况删去所有的数,那么时间为n-1+(n-2)+(n-3)+……+0 ,所以最终的时间复杂度为O(N^2)

    算法心得:

    其实一开始觉得贪心嘛,套路就是最大最小,但其实不一定,这道题就是。只是阶段性的最大最小。所以还是不要被贪心迷惑。

  • 相关阅读:
    家庭记事本开发进度1
    仓库信息管理系统
    文件与流动手动脑和课后作业
    课堂测试
    Java异常处理
    动手动脑五
    动手动脑4
    记录类的个数
    数据结构
    操作系统
  • 原文地址:https://www.cnblogs.com/aresjohnson/p/11887063.html
Copyright © 2020-2023  润新知