C语言实现之数字中的最大数字组合

本文介绍了如何使用C语言解决一个数学问题:在整数n=92081346718538中删除10个数字,使剩余数字按原顺序组成的新数最大化。通过贪心算法,优先选择从高位开始的数字,最终找到的最大4位数是9888,删除的数字为2,0,1,3,4,6,7,1,5,3。" 131364039,10282337,华为OD机试真题:第K个排列的JS解法,"['华为OD机试真题', 'javascript', '开发语言']

接上一篇,还是我同学给的题目,第2个。

*写的比较仓促,如果有更简便、执行效率更高的方法还请不吝赐教,当然我的如果有问题请大家给指出。

题目:

        请在整数n=92081346718538中删除10个数字,使得余下的数字按原次序组成的新数最大。要求如下:
 
       (1)整数n和删除数字的个数“10”在源程序中完成赋值,程序直接输出运行结果;
         (2)程序结果输出先后被删除的数字(之间以逗号分隔)和删除后所得的最大数。

分析:

   (1)此题中n这个大整数,又要从中删除,肯定需要用一个字符数组或数字数组存储,这样会比较方便。

   (2)这个大整数n一共有14位,从中删除10位,也就是说留下一个4位的最大数字(注意数字顺序不能颠倒),与其删除10个数字,不如从中找出符合条件的4个数字。

   (3)从中找数字的话,千位一定是n的千位会千位以左,其他位以此类推,否则剩下的数字已经不够组成4位数的了。

   综合上述我们的分析,其实这就是利用贪心算法,优先寻找最大的4数字。

思路:

    我是这样想的,这个n直接当个字符串处理,反正和数组一样都能随机访问,初始化的时候还方便,贪心算法,当然我们当然是先搜索数字9,要是里面有4个9的话,当然我们找的最大4位数是9999。先找最大的9,如果找不到,再找8,找不到8再找7,以此类推,找完一位,再找下一位,这要找四位,按要求输出的时候,把在n中对应的两位之间的数字(即要删除的数字)输出出来就OK了。

实现:

(写的仓促了点,都写到main里面了,没仔细分。)

#include <stdio.h>
#include <string.h>


/**********************
*函  数:int main()    *
*参  数:无            *
*功  能:主函数         *
*返  回:0             *
**********************/
int main()
{
    char * n = "92081346718538";
    int result = 0;
    //int StartSite = 0;                        //记录起始位置
    int validSite  = 0;                         //记录当前有效位置
    int lastValidSite = 0;                      //记录上一次有效位置
    int length = strlen(n);
    int max = 9;
    int loop = 0;
    int circle = 0;
    int flag;                                   //找到最大数字标志

    while(1)
    {
        flag = 0;                               //重置最大数字标志
        //circle = StartSite;                   //初始化起始位置

        while(n[circle] != '\0')
        {
            //判断剩余长度是否有效(即当前位置之后剩余的数字长度必须大于等于剩余需要的数字长度)
            if(length - circle < 4 - loop)
            {
                break;                          //数字长度不满足条件,跳出此次循环
            }
            //判断数字是否是当前检索的最大数字
            if(n[circle] == max + 0x30)
            {
                result *= 10;
                result += (n[circle] - 0x30);
                lastValidSite = validSite;
                validSite = circle;

                flag = 1;                       //修改标志位
                break;
            }
            circle++;                           //循环变量自增,判断下一位数字
        }
        //判断标志位是否置位(即找到最大数字)
        if(flag)
        {
            //循环打印出此次有效位和上次有效位之间无用(被删除)的数字
            for(circle = lastValidSite + 1; circle < validSite; circle++)
            {
                printf("%c,", n[circle]);
            }
            //自增计数变量并判断是否到达4位数
            if(++loop == 4)
            {
                lastValidSite = validSite;      //当前有效位设为上一次
                validSite = length;             //将结束设为当前有效位
                //打印出最后一个有效数字到原始数字最后之间的无用(删除)的数字
                for(circle = lastValidSite + 1; circle < validSite; circle++)
                {
                    printf("%c,", n[circle]);
                }
                break;
            }
            max = 9;                            //每次找到最大数字之后,重置要寻找的最大数字目标
        }
        //标志位未置位,说明没要要查找的最大目标
        else
        {
            max--;                              //寻找的最大数字目标自减,以便重新查找
        }
        circle = validSite + 1;                 //重置循环的起始位置
    }
    printf("%d\n", result);
    return 0;
}

结果:

2,0,1,3,4,6,7,1,5,3,9888

(2178 x 4 = 8712)

总结:

      这个可能也没什么难的,主要是转换一下思考方式,在这个题里,删掉10个数对应的也就是留下4个数,只要这样想,用贪心算法的思想来处理就OK了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值