> 文档中心 > 蓝桥杯——一篇搞懂大数问题

蓝桥杯——一篇搞懂大数问题

大家好,我是璐画

📒博客主页:璐画的个人主页
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📌本文由璐画原创,CSDN首发!
📆首发时间:🌴2022年3月21日🌴
✉️坚持下去的,都是因为热爱吧!
💭参考书籍:📚《labuladong的算法小抄》
🍭作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!

特别声明:本文我是学习过‘付东来’大佬的书然后总结出来的文章,想学习的小伙伴可以买大佬那本《labuladong的算法小抄》,写的很好

目录

1、大数类问题

2、例题

求n!

最小公倍数

星期(自己起的名)

3、总结


1、大数类问题

我们先来看下大数类怎么使用吧

java中的基础数据类型能存储的最大的二进制数是 2 ^ 63 - 1,
对应的十进制数是9223372036854775807,也就是说只要运算过程中会超过这个数,就会造成数据溢出,从而造成错误.

而java.math.*包中提供了大数类,其理论上可以存储无限位的大数,只要内存足够的话。
大数类又分为整数和浮点数.即BigInteger and BigDecimal

大数类的对象不能直接进行运算,需要调用类中相应的方法,并且方法的参数必须和调用的类相同,BigInteger不能调用BigDecimal, 不能作为其方法参数, 即整数和浮点数不能混合运算.
举例了一些常用的方法,不需要背会,需要用的时候查java API就行了。

基本使用

赋值

BigInteger a;
BigDecimal b;
//注意 val 不能超过 long 类型的最大取值9223372036854775807, 超过int时要在数后面加L如:
a = BigInteger.valueOf(123456789101112L); //大于int范围的要加L
b = BigDecimal.valueOf(123456.12341235); // 超出的小数位数会自动舍弃

求最大公因数

BigInteger a, b, c;
a = BigInteger.valueOf(987654321); // 赋值为 987654321
b = BigInteger.valueOf(123456789); // 赋值为 123456789
c = a.gcd(b);
System.out.print(c);

BigDecimal舍入问题

ROUND_HALF_UP 四舍五入 即1.55 变为1.6, -1.55变为-1.6
ROUND_HALF_DOWN 五舍六入 即 1.55 变为 1.5, -1.5变为-1.5
ROUND_DOWN 向零舍入。 即1.55 变为 1.5 , -1.55 变为-1.5
......
除法
public class Main{
    public static void main(String[] args){
        BigDecimal a, b, c;
        a = BigDecimal.valueOf(1.51);
        b = BigDecimal.valueOf(1.37);
        c = a.divide(b,100,BigDecimal.ROUND_DOWN);//采用向0舍入并并保留100位小数
        System.out.println(c);
    }
}

接下来我们来看一些题,大数类只需要会用就好,具体可以比赛时查API,但是注意比赛用的API是英文的,我也不知道为什么,一个国内比赛用英文文档,就很迷

2、例题

求n!

阶乘我相信大家都听说过,如5!=1*2*3*4*5,那么100!等于多少呢,请写出具体代码实现  

* 题目:n! * 对输入的正整数n,计算出n!的准确值。 * 输入格式: * 输入一个正整数n(0<n<=100). * 输出格式: * 输出n!。 * 样例1: * 输入: * 9 * 输出: * 362880 * 样例2: * 输入: * 100 * 输出: * 93 326215 443944 152681 699263 * 856266 700490 715968 264281 621468 592963 * 895217 599993 229915 608914 463976 156578 * 268253 679920 827223 758251 185210 916864 * 000000 000000 000000 000  //非递归版本,方便理解思想import java.math.BigDecimal;import java.util.Scanner;public class 求阶乘{    public static void main(String args[]){ Scanner sc= new Scanner(System.in); int num = sc.nextInt(); BigDecimal result= new BigDecimal(1); for(int i=1;i<=num;i++){     BigDecimal i_value= new BigDecimal(i);     result = result.multiply(i_value); } System.out.println(result);    }}

 这道题,大家配合着查找API,看看里面大数类的哪些方法被使用了,这些个方法又是干什么的,这里先暂停5分钟,弄明白了在看后面的题

最小公倍数

/*为什么 1 小时有 60 分钟,而不是 100 分钟呢?这是历史上的习惯导致。

但也并非纯粹的偶然:60 是个优秀的数字,它的因子比较多。

事实上,它是 1 至 6 的每个数字的倍数。即 1,2,3,4,5,6 都是可以除尽 60。

我们希望寻找到能除尽 1 至 nn 的的每个数字的最小整数。

不要小看这个数字,它可能十分大,比如 nn = 100, 则该数为:

69720375229712477164533808935312303556800*/

这道题该怎么做,怎么使用大数类和它的API呢,这里也先暂停下,大家先自己做一下,然后看答案

思路:这道题考的大数类,如果求的是连续多个数字的最小公倍数,只需要先求前两个的
最小公倍数,然后求第三个数和前面最小公倍数的最小公倍数,以此类推

public class 最小公倍数 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int N = sc.nextInt();BigInteger a = new BigInteger("1");BigInteger b = new BigInteger("2");BigInteger c = new BigInteger("1");int ans = 2;while(ans<=N) {a = f(a,b);b = b.add(c);ans++;}System.out.println(a);}//求最小公倍数public static BigInteger f(BigInteger a,BigInteger b) {return a.divide(gcd(a,b)).multiply(b);}//求最大公约数public static BigInteger gcd(BigInteger a,BigInteger b) {return b.toString().equals("0")?a:gcd(b,a.mod(b));}}

到这里为止,我相信大家都明白了一些吧,那么我们再来看一道题,这道题是2021年蓝桥杯第一题,我就是这一届参加的,难度比之前的难多了,大家不要对这个比赛掉以轻心了啊

求星期(自己起的名)

今天是星期六,那么20^22(20的22次方)天以后,是星期几?

(问题具体忘了,这是问题大概)

这个的话,一看数据就知道用大数类,大家先看看

public class 星期几 {public static void main(String[] args) {BigInteger b1 = new BigInteger("20");//求20^22等于多少b1 = b1.pow(22);//求等于多少个星期b1 = b1.mod(new BigInteger("7"));System.out.println(b1);}}

这个题就很简单了,求出20^22是多少个星期,最后发现取模7多出来一天,那么就那星期六+1,答案就是星期日对吧,不难,就是大数类的基本使用

3、总结

今天的大数类就先到这里,大数就是基本API使用,也不会出什么难题,大家弄懂这些,大数类必拿下