蓝桥杯——试题 算法提高 计算超阶乘

题目:

试题 算法提高 计算超阶乘

 
资源限制
时间限制:1.0s   内存限制:256.0MB
问题描述
  计算1*(1+k)*(1+2*k)*(1+3*k)*...*(1+n*k-k)的末尾有多少个0,最后一位非0位是多少。
输入格式
  输入的第一行包含两个整数n, k。
输出格式
  输出两行,每行一个整数,分别表示末尾0的个数和最后一个非0位。
样例输入
15 2
样例输出
0
5
数据规模和约定
  1<=k<=10,1<=n<=1000000。
 
思路:
一开始,自己就想着从最后一个数一直往前乘,每次得到一个乘积后就对这个结果进行末尾0的计数,并找到此次最后一位非0的数,直到while循环结束。这里整个循环过程我都没有对ans计算的结果求模,才导致每次提交到OJ都AC不了,以为这里求模了会对结果有影响,所以尝试了很多次改了很多地方,就唯独这个地方没有走心,哎!!!后面看了网友的AC代码,都用了求模,这下才恍然大悟,真的要求模啊,不然数会超越long类型的范围。
 

没有求模的代码(一开始自己写的):

 1 package com.lzp.algorithmAdvance.p2;
 2 
 3 import java.util.Scanner;
 4 
 5 /**
 6  * @Author LZP
 7  * @Date 2021/3/16 10:17
 8  * @Version 1.0
 9  *
10 试题 算法提高 计算超阶乘
11 
12 
13 资源限制
14 时间限制:1.0s   内存限制:256.0MB
15 问题描述
16   计算1*(1+k)*(1+2*k)*(1+3*k)*...*(1+n*k-k)的末尾有多少个0,最后一位非0位是多少。
17 输入格式
18   输入的第一行包含两个整数n, k。
19 输出格式
20   输出两行,每行一个整数,分别表示末尾0的个数和最后一个非0位。
21 样例输入
22 15 2
23 样例输出
24 0
25 5
26 数据规模和约定
27   1<=k<=10,1<=n<=1000000。
28 
29  这是我一开始的思路
30  第一下竟然没有想到求模,导致计算的数超过了long,使得结果总是错,每次提交都AC不了
31  */
32 public class Main {
33     private static int n;
34     private static int k;
35     public static void main(String[] args) {
36         Scanner input = new Scanner(System.in);
37         n = input.nextInt();
38         k = input.nextInt();
39         input.close();
40 
41         int end = 1 + (n - 1) * k;
42         long ans = 1;
43         long count = 0;
44         int endNum = -1;
45         while (end > 0) {
46             ans = ans * end;
47 
48             String ansStr = String.valueOf(ans);
49             // 找出有多少个零
50             int index = ansStr.length() - 1;
51             while (ansStr.charAt(index) == '0') {
52                 index--;
53             }
54             // 每次找最新的最后一位非0位是多少。
55             endNum = Integer.parseInt(ansStr.substring(index, index + 1));
56             // 不包括index本身
57             int zNum = ansStr.length() - 1 - index;
58             if (zNum > 0) {
59                 count += zNum;
60                 ans = Long.parseLong(ansStr.substring(0, index + 1));
61             }
62             end -= k;
63 
64             // 就是因为没有求模,才导致一次次提交都错
65             // ans %= 10000000; // 一开始没有这一行
66         }
67 
68         System.out.println(count);
69         System.out.println(endNum);
70     }
71 }

AC代码:

 1 package com.lzp.algorithmAdvance.p2;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 import java.util.Scanner;
 6 
 7 /**
 8  * @Author LZP
 9  * @Date 2021/3/16 10:17
10  * @Version 1.0
11  *
12 试题 算法提高 计算超阶乘
13 
14 
15 资源限制
16 时间限制:1.0s   内存限制:256.0MB
17 问题描述
18   计算1*(1+k)*(1+2*k)*(1+3*k)*...*(1+n*k-k)的末尾有多少个0,最后一位非0位是多少。
19 输入格式
20   输入的第一行包含两个整数n, k。
21 输出格式
22   输出两行,每行一个整数,分别表示末尾0的个数和最后一个非0位。
23 样例输入
24 15 2
25 样例输出
26 0
27 5
28 数据规模和约定
29   1<=k<=10,1<=n<=1000000。
30 
31  */
32 public class MainAC {
33     private static int n;
34     private static int k;
35     public static void main(String[] args) {
36         Scanner input = new Scanner(System.in);
37         n = input.nextInt();
38         k = input.nextInt();
39         input.close();
40 
41         // 用于记录0的个数
42         int count = 0;
43         long sum = 1;
44         // i从 1~n-1
45         for (long i = 1; i < n; i++) {
46             sum *= (1 + (i * k));
47             // 去0 这里要求sum > 9是为了防止sum = 0的情况,如果sum真的等于0的话,那么后面跟sum相乘就会全为0
48             while (sum % 10 == 0 && sum > 9) {
49                 sum /= 10;
50                 count++;
51             }
52             // 防止超过long,就得求模
53             sum %= 1000000;
54         }
55         System.out.println(count);
56         System.out.println(sum % 10);
57     }
58 
59 }
posted @ 2021-03-16 21:59  没有你哪有我  阅读(108)  评论(0编辑  收藏  举报