贪心题:萌萌哒的GG

萌萌哒的GG

时间限制: 10 Sec   内存限制: 128 MB

题目描述

11月15号是GG的破蛋日,这一天萌萌的GG很早就起床,小(zi)小(xi)打扮了一下,就去参加传说中的ACM-ICPC亚洲赛了。 这一去让原本萌萌哒的GG变得更加萌 了,在那凶残的北京赛区中GG被虐的萌萌哒连回家的路都忘记了。于是萌萌的GG便向英勇帅气的DX问起路来,但是DX不想让GG这么容易就能回家,于是他出了一道ACM题,说只要GG能够做出来,就带他回家。 呜呜~~~~(>_<)~~~~ ,这可难倒GG,于是GG哭着向聪明的你请教,希望你能做出来,不然GG就回不了家了。。。 题目是这样紫滴:

输入

数据有T组,给你两个值s,k ( 1 <=T <= 10000,2 <= strlen(s) <= 1000, 0 <= k < strlen(s)); s表示一个字符串(只包含数字,没有前导0),k表示在这个s中删除k个数,使最后得到数(没有前导0)最小。

输出

对于每一组数据输出“Case #x: y”,x表示第几组,y表示删除后得到的最小的数,注意双引号不要输出。

样例输入

291623 21063 1

样例输出

Case #1: 123Case #2: 63

提示

第一组数据删除9和6得到数最小; 第二组删除1,比删除其他数,得到的值小;

来源


分析:

1、明天就要蓝桥杯比赛了,今天就猛刷题。读完这道题后,看见输入数字位数会达到1000位,就会想到数组处理,然后会想到不是常规做法,就寻找其中的计算方式。

2、好久没有做过贪心题了,这是一道贪心题。当我们拿到一个数后,输出最小,肯定是从最高开始判断,删除后位数肯定小于等于strlen(s)-k,所以,从最高位开始遍历,寻找相对于下一位大的数字,然后删除。如91623,9比1大,所以删除9,然后遍历,1比6小,不删除,继续遍历,接着6比2大,所以删除6。到此,已经删除2位数字了,结束遍历。用这种方法解决,复杂度是相当低的,10以内就10个数,必删除一个。若是个递增数列,就删除后面数字呗。

3、程序需要处理一下细节,我为了ac它,就没把程序简化了。首先要考虑到当一样大的时候,还要回去删除数字,如9996623,删除2个数字吧,比到9比6时,删除9,然后需要判断前面是否有9。另外就是输出时,注意没有前导0.


LANGUAGE :C++

CODE:

#include <iostream>
#include <cstring>
using namespace std;

int main()
{
    int t,cnt;
    char arr[1005];
    cin>>t;
    int count=0;
    while(t--)
    {
        cin>>arr;
        cin>>cnt;
        //cout<<arr[0]<<endl;
        int m=0;
		int ans=0;          //删除相同数字,移位时不再从0开始了 
        for(int i=0;cnt&&i<strlen(arr)-1;i++){
            if(arr[i]>arr[i+1]){
                //cout<<arr[i]<<endl;
                bool flaggg;    
                do{
					flaggg=false;
                    for(int j=i;j>ans;j--){
                        arr[j]=arr[j-1];
                        flaggg=true;    //判断前面是否有没有删除的数字 
                    }
                    cnt--;  
                    m++;   //记录删除多少数字后,输出时的起点位置 
                    ans++;
                    //cout<<cnt<<endl;
                }while(arr[i]>arr[i+1]&&cnt&&flaggg); //判断前面是否有相同的数字 
            }
        }
        bool flag=true;
        bool fla=true;
        count++;
        cout<<"Case #"<<count<<": ";
        //cout<<m<<endl;
        for(int i=m;i<strlen(arr)-cnt;i++)
        {
            if(arr[i]!='0'&&flag)   //前导是0时不输出 
            {
                cout<<arr[i];
                flag=false;
                fla=false;
            }
            else if(!flag)         //不是前导0或其他数输出 
                cout<<arr[i];
        }
        if(flag&&fla)   //如果剩余的全是0时,输出结果0 
        	cout<<0;
        cout<<endl;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值