2、阶乘求和

解这道题之前首先需要会计算下面的问题。

1、求N的阶乘末尾存在多少个0。

(1)为什么会产生0?这是因为2x5=10,只要是2和5的公倍数相乘就会产生“0”

(2)输出1!~  100!的值,观察发现每隔5个数就产生一个0,每隔5x5个就多加一个0,(比如25,50,75,100)每隔5x5x5个数又增加一个0(比如125,250,750)...  并且100!有24个“0”。

    @Test
    public void test2(){
        BigInteger big = new BigInteger("1");
        BigInteger big2 = new BigInteger("1");
        BigInteger sum = new BigInteger("0");
//        此方法返回 -1、0 或 1,因为此 BigInteger 在数值上小于、等于或大于 val。
//        只要小于101就继续
        while(big2.compareTo(new BigInteger("101")) == -1){
            big = big.multiply(big2);
            System.out.println(big);
            sum = sum.add(big);
            big2 = big2.add(new BigInteger("1"));
        }
        System.out.println("sum:"+ sum);
    }

(3)规律:

eg:

100!有多少个“0”?

100/5 = 20 ->  100里面有20个数是5的倍数;

100/25 = 4 ->  100里面有4个数是25的倍数;

100/125 = 0 ->100里面没有125的倍数,

因此100里面有 100/5 + 100/25 = 20+4 = 24个“0”。

eg:

1000!有多少个“0”?

1000/5 = 200 ->  1000里面有200个数是5的倍数;

1000/25 = 40 ->  1000里面有40个数是25的倍数;

1000/125 = 8 ->1000里面有8个数是125的倍数;

1000/625 = 1 ->1000里面有1个数是625的倍数;

1000/3125 = 0 ->1000里面有0个数是3125的倍数;

因此100里面有 1000/5 + 1000/25 + 1000/125 + 1000/625 = 200+40+8+1 = 249个“0”。

以此类推。

注意:尽管25=5x5有两个因子5,但是在计算5的倍数的时候已经算过一遍了,所以这里只算一次就可以了。

最终求n!末尾有几个“0”的代码:

(BIgInteger是大整数,可以计算较大的n!)

public void test(){

//        法1

//        int n = 2009;
//        int param = 5;
//        int count = 0;
//        int c = 1;
//        while(c != 0){
//            c = n/param;
//            count += c;
//            param *= 5;
//        }
//        System.out.println(count);

//       法2

        int n = 2009;
        int count = 0;
        for(int i = 0; i < n; i++){
            n /= 5;
            count += n;
        }
        System.out.println(count);


//        法3
  BigInteger big = new BigInteger("1000");
        BigInteger count = new BigInteger("0");
        while( big.compareTo(new BigInteger("0")) == 1){
            big = big.divide(new BigInteger("5")); //除法
            count = count.add(big);
        }
        System.out.println(count);
}

2、现在给出数字Q,请找到最小的N,使得N!末尾恰好有Q个0。

eg:
Q = 24; 求N=?

(二分查找法)

 public int cnt(int n){
        int count = 0;
        for(int i = 0; i < n; i++){
            n /= 5;
            count += n;
        }
        return count;
    }
    @Test
    public void test4(){
        int Q = 249;
        int left = 0;
        int right = Q * 5;
        int middle = 0;
        while(left <= right){
//            中间数
            middle = (left+right)/2;
            if(cnt(middle) < Q){
                left += 1;
            }else if(cnt(middle) > Q){
                right += 1;
            }else{
                break;
            }
        }
        System.out.println(middle);
    }

3、阶乘求和

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值