c++编程题 保留最大的数

终于到家了!开始好好学习算法及数据结构〜

这是一道两天前就在写的题,算法是想出来了,但是读入的时候总是出现问题!

分享下我的解题历程吧〜

题目如下:

题目描述

给定一个十进制的正整数数目,选择从里面去掉一部分数字,希望保留下来的数字组成的正整数最大。

输入描述:

输入为两行内容,第一行是正整数number,1 ≤ length(number) ≤ 50000。第二行是希望去掉的数字数量cnt 1 ≤ cnt < length(number)。

输出描述:

输出保留下来的结果。

示例1

输入

325 1

输出

35

以下是我最开始的代码:

#include<iostream>
#include<math.h>
#include<string>

using namespace std;

int main(void){
    int number=0; //读入的数据
    int cnt=0;    //读入数据要减去的位数

    cin>>number>>cnt;

    int a[50000];
   
    int count=0;    //读入数据的位数

    for(int i=0;i<50000;i++){
        a[i]=number % 10;     //按位数存储每位数(通过取余)
        number/=10;
        if(a[i]!=0) count++;
        else break;
    }

    if(a[0]==0) count++;

    int index=0;        //减去对应位数后剩下数字的位数
    index=count-cnt;

    int jindex=0;    //找到起始的最大一位数的下标

    int max=a[index];
    for(int j=index-1;j<count;j++){    //因为一共有index位,所以最大的第一位数肯定在a[index-1]~a[count-1]之间(其后面应有足够的位数使得数字减去后仍有index位)
        if(a[j]>=max) {        //找到最大的第一位数,存在max里,下标为jindex
            max=a[j];
            jindex=j;
        }
    }

    int kmax[5000];    //存储剩下最大的index-1位数

    for(int k=jindex-1;k>=0;k--){    //从之前的jindex-1开始寻找
        kmax[k]=a[k];
        for (int h=k;h>=(index-1+(k-jindex));h--){          //同理,其后面应有足够的位数使得数字减去后仍有(index-1+(k-jindex)位
            if(a[h]>kmax[k]){
                kmax[k]=a[h];
                a[h]=0;
            }
        }
    }
    string s;
    for(int x = jindex-1;x>=(jindex-index+1);x--){    //整数转字符串并依次拼接
        string p=std::to_string(kmax[x]);
        s+=p;
    }
    string t=std::to_string(max);
    t+=s;
    cout<<t;
}

用到的知识点:

1、数字转字符串

string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);

例子:

// to_string example
#include <iostream>   // std::cout
#include <string>     // std::string, std::to_string
 
int main ()
{
  std::string pi = "pi is " + std::to_string(3.1415926);
  std::string perfect = std::to_string(1+2+4+7+14) + " is a perfect number";
  std::cout << pi << '\n';
  std::cout << perfect << '\n';
  return 0;
}

---------------

最开始自己想的数据测的,得到的结果都是对的,所以雄心壮志的点了“保存代码并测试”,结果告诉我通过率只有20%,好吧..一下打趴。

于是开始多换几个数据,还是没问题啊?怎么回事呢?

胡乱输入了一个很长的数据,发现程序根本没等待我输入第二个数据,就自己跳出来一个结果(而且当然是不对的)。

然后才反应过来 - 啊,INT溢出了!

改成double = 0呢?

----

这-8是什么鬼!还是读入有问题啊!

一拍脑门,嘿,这傻子,双类型是浮点数,不能取余啊!想啥呢!

改成long long int number = 0!

嘿嘿〜成功!

再去测!

ok...

又去试了更长的数,果然还是读入的问题..而且似乎这个网站大多数的测试用例都是长数据..

我完全懵比不知道咋个办了......

只好看看通过的大佬的代码,学习下吧..

#include <bits/stdc++.h>
   
using namespace std;
const int maxn = 5e4 + 20;
char str[maxn], s[maxn];
int k, top = 0, num = 0;
   
int main() {
    scanf("%s%d", str, &k);
    int len = strlen(str);
    for (int i = 0; i < len; i++) {
        while (top > 0 && s[top - 1] < str[i] && num < k) {
            num++;
            top--;
        }
        s[top++] = str[i];
    }
    top = min(top, len - k);
    s[top] = '\0';
    puts(s);
    return 0;
}

......我承认我被秀到了。

原来读入按字符串就可以了啊!摔!

-----------------

读入代码改为:

long int count=number.length();        //注意str.length()返回的数据类型是size_t,故前面用long int,否则会报警告
    for(int i=0;i<count;i++){
        a[count-1-i]=int(number[i])-48;    //这里也需要修改,之前代码是a[0]存的个位数,如果不改就是a[0]存最高位数了(字符串的第一个字符)。而且转换为int后得到的是ASCII的号码,如‘1’对应49,故应该减去48.
    }

最终代码如下:

#include<iostream>
#include<math.h>
#include<string>


using namespace std;

int main(void){
    string number;    //这里最开始初始化只改了类型,忘了把=0删掉,一直报越界错误,我还一直以为是下面读取的问题。。。
    int cnt=0;
    cin>>number>>cnt;
    int a[50000];
    long int count=number.length();
    for(int i=0;i<count;i++){
        a[count-1-i]=int(number[i])-48;
    }

    long int index=0;
    index=count-cnt;
    long int jindex=0;
    int max=a[index];
    for(long int j=index-1;j<count;j++){
        if(a[j]>=max) {
            max=a[j];
            jindex=j;
        }
    }

    int kmax[5000];
    for(long int k=jindex-1;k>=0;k--){
        kmax[k]=a[k];
        for (long int h=k;h>=(index-1+(k-jindex));h--){
            if(a[h]>kmax[k]){
                kmax[k]=a[h];
                a[h]=0;
            }
        }
    }
    string s;
    for(long int x = jindex-1;x>=(jindex-index+1);x--){
        string p=std::to_string(kmax[x]);
        s+=p;
    }
    string t=std::to_string(max);
    t+=s;
    cout<<t;
}

测试长数据:

完全OK!

再去测通过率!

.........

我...无话可说

求大佬救救孩子啊!!

猜你喜欢

转载自blog.csdn.net/qq_36770641/article/details/81842822
今日推荐