第十四届蓝桥杯JavaB_题解

前言

本文章是对第十四届蓝桥杯JavaB组题目写的题解,代码均经过测试,但存在部分非更优解,故请酌情参考。

试题A:阶乘求和

思路一:

        阶乘问题一般是分解因子,而根据本题条件的隐喻可知,阶乘中必然有大部分数据无需计算,那么如何定位需要计算的数据与不需要计算的数据就十分重要。而又因为因子中2x5=10,那么1 000 000 000有几个零,就要有几对2x5,这样的阶乘和必然后九位全为0,换句话说这样的阶乘就不需要考虑到计算中,摸索到这个规律后,我们只需要找到这个数字就可以了。经过一顿乱造可得,n!=90!时刚好是这个区分线,所以我们只需要计算1!+...+90!即可。

思路二:

我们可以正常求解,并加入判断只要数字取余1 000 000 000后的结果为0时,停止累加计算即可。

public class test {
    public static void main(String[] args) {
        long max = 202320232023L;
        long last = 1000000000;
        long a = 1;
        long b = 0;
        for (int i = 1; i <= max; i++) {
            //求出每个数的阶乘的后九位
            a = (a * i) % last;
            //当此处的条件成立时,说明运算出的数的阶乘的后九位已经全部为0,就可以停止运算输出结果了
            if (a % last == 0) {
                System.out.println(b);
                return;
            } else {
                //求运算到目前为止的所有数的阶乘之和的后九位
                b = (b % last + a % last) % last;
            }
        }
    }
}

试题B:幸运数字

思路:

        没什么好说的,按照题目要求进行筛选即可。在这里浅浅的分析下时间复杂度,首先按照题意可知要找第2023个幸运数字,那也就是说我们需要从1开始对他进行“幸运数”判断,而每个数要跑4个进制的check,所以时间复杂度应该是O(n^2)。

        根据下图的数量级变化曲线可知,大概率可以算出,故不做优化处理直接干。

import java.math.BigInteger;

/**
 * Lucky Number
 * 第2023个应该是215040
 */
public class T2 {
    public static void main(String[] args) {
        long i = 1;
        int theNum = 0;

        while(true){
            if(check(BigInteger.valueOf(i))){
                ++theNum;
            }
            if(theNum == 2023){
                System.out.println(i);
                return;
            }
            ++i;
        }
    }

    public static boolean check(BigInteger num){
        String num2 = num.toString(2);//转成二进制字符串
        String num8 = num.toString(8);
        String num10 = num.toString(10);
        String num16 = num.toString(16);

        BigInteger num2add = BigInteger.ZERO;
        for (int i = 0; i < num2.length(); ++i) {
            num2add = num2add.add(new BigInteger(num2.charAt(i) + "", 2));
        }
        if (num.mod(num2add).compareTo(BigInteger.ZERO) != 0) {
            return false;
        }

        BigInteger num8add = BigInteger.ZERO;
        for(int i=0; i <num8.length(); ++i){
            num8add = num8add.add(new BigInteger(num8.charAt(i)+"",8));
        }
        if(num.mod(num8add).compareTo(BigInteger.ZERO)!=0){
            return false;
        }

        BigInteger num10add = BigInteger.ZERO;
        for(int i=0; i <num10.length(); ++i){
            num10add = num10add.add(new BigInteger(num10.charAt(i)+"",10));
        }
        if(num.mod(num10add).compareTo(BigInteger.ZERO)!=0){
            return false;
        }
        BigInteger num16add = BigInteger.ZERO;
        for(int i=0; i < num16.length();++i){
            num16add = num16add.add(new BigInteger(num16.charAt(i)+"",16));
        }
        if(num.mod(num16add).compareTo(BigInteger.ZERO)!=0){
            return false;
        }
        return true;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值