蓝桥杯(数位排序)

当我看到这个题时的思路是:用冒泡排序的方式对区间[1,n]之间的元素进行排序,排序条件为 后一项的位数和 < 当前项的位数时就交换元素,即是 (arr[j]>arr[j+1]); 这样使得数组元素的位数和相等时保存相对顺序。但是,这种方法会超时,导致提交答案不能全对。因为n,m 的最大值为10的6次方。所以我换了一个思路。

1.定义目标数组 arr 。题目要求是求排序后的第 m 项,所已要定义一个整形数组来存储[1,n], 但是 n 最大为10的6次方,因此不能用 int arr[10000000]={0}这种方式申请空间,而是用malloc函数申请空间。

2.定义三个变量n,m,ans。n 为输入的区间,m 为排序后的第m个元素,ans 只用于表示目标数组 arr
的下标。
3.第一层循环 for(i=1;i<=54;i++):这一层循环的意思是在区间 [1,n] 之间查找元素位数和为 i 的元素,比如在区间 [1,100] 之间,当 i=1 时:元素位数和为1的元素只有{1,10,100},且该顺序为排序后的顺序;当 i=2 时:元素位数和为2的元素有{2,20},同时也为排序后的顺序。当我们枚举到 i=2时,会发现排序后的前5个元素为{1,10,100,2,20};依次类推到 i=54时就得到了排序后后答案。为什么 i<=54 ?每位最大为9,同时 n 最多有6位。因此最大位数和为6x9=54;

4.第二层循环for(j=1;j<=n;j++):重复枚举区间[1,n],找到元素位数和与目标值 i 相等的元素,然后存入目标数组 arr,并让下标 ans++;由于是从小到大枚举区间的,那么最终的答案也一定是符合条件增序的。进一步讲解,每次都是从[1,n]之间选出位数和与i相等的那些元素,并存入目标数组。

5.由于每个数都要求位数和,所以我们可以单独编写一个求位数和的函数。

6.得到目标数组 arr,要求输出第 m 个元素,即是目标数组 arr 下标为 m-1 的元素(arr[m-1]);

如有错误,请留言指正!!!

#include <stdio.h>
#include <stdlib.h>
int getval(int s)//求每个数的数位和
{
    int val = 0;
    while (s)
    {
        val += s % 10;
        s /= 10;
    }
    return val;
}
int main(int argc, char* argv[])
{
    // 请在此输入您的代码
    int* arr = (int*)malloc(sizeof(int) * 10000001);//申请数组用来存放结果值,直接 
                                                                         //定义 int arr[10000001]是不可以的
    int n, m,ans=0;//n,m为输入值,ans只用于遍历目标数组arr;
    scanf("%d", &n);
    scanf("%d", &m);
    for (int i = 1; i <=54; i++)//填充目标数组,每个数字的位数和是否为 i 值
    {
        for (int j = 1; j <=n; j++)//重复枚举数值区间[1,n],查看是否有 位数和=i 的值
        {
             if(i==getval(j))//如果有满足条件的目标值,则填入目标数组 arr
             {
               arr[ans++]=j;
             }
        }
    }
    printf("%d ", arr[m-1]);//输入第 m 个数,注意下标减一
    free(arr);//释放申请的空间
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

她没有救赎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值