【牛客】NC19841 数学(Java)

这篇博客介绍了如何在大数据量下判断一个数是否是3,5,8,11的倍数。提出了两种策略:planA利用数的性质进行判断,planB则使用BigDecimal类。代码实现分别演示了这两种方法,并强调了不断学习和实践对提升算法能力的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

📖 题目⭐⭐:

链接:https://ac.nowcoder.com/acm/problem/19841 来源:牛客网

某年某月某天的数学课上,Actci正在遨游宇宙呢,对于他的屡教不改,她的数学老师决定难为一下Actci,将他叫醒。
“咳咳,我现在给出一个数a(0≤a≤ 1 0 10000 10^{10000} 1010000,判断a是否是3,5,8,11中某些数的的倍数,你只有一秒钟的时间,答不上来的话,呵,%#W@…”。

作为他后桌的你怎么能看着Actci“受害”呢,于是你决定帮帮他。

💡 思路:

第一眼看到数据,就知道用正常的求余等于0根本无法通过,所以一下想到的是第一种方法:

⌛ plan A: 这个思路是根据3,5,8,11的倍数所拥有的性质来解决:

  1. 3的倍数:各个位相加能被3整除。

  2. 5的倍数:结尾为0或5(数字0除外)

  3. 8的倍数:后三位能够被8整除(不足三位前面补零或者直接除即可)

  4. 11的倍数:(两个性质选一个就行)

    a. 若一个整数的奇位数字之和与偶位数字之和的差能被11整除,则这个数能被11整除。

    b.将一个数从个位开始两两分隔,若所有分隔开的数和为11的倍数,则这个数为11的倍数。

⌛ plan B:直接使用BigDecimal类判断能否整除即可,原本以为用BigDecimal这个类装的数据没那么多,没想到能够装这么大的数(颠覆认知观😲!!)

💻 代码A:

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        String s = input.next();
        long sum = 0;
        int a[] = new int[4];
        int count = 0;
        for(int i = 0; i<s.length();i++){
            sum+=s.charAt(i)-'0';
        }
        if(s.equals("0")){
            System.out.println("No");
            return;
        }
        if(sum%3==0){
            a[count++]=3;
        }
        if(s.charAt(s.length()-1)=='5'||s.charAt(s.length()-1)=='0'){
            a[count++]=5;
        }
        int temp = 0;
        if(s.length()>=3){
            temp=Integer.parseInt(s.substring(s.length()-3));
        }else{
            temp = Integer.parseInt(s);
        }
        if(temp%8==0){
            a[count++]=8;
        }
        int k,w;
        int length = s.length();
        if(length%2==0){
            k=0;
            sum = 0;
        }else{
            k=1;
            sum = Integer.parseInt(s.substring(0,1));
        }
        for(;k<length;k=k+2){
            sum =sum+Integer.parseInt(s.substring(k,k+2));
        }
        if(sum%11==0){
            a[count++]=11;
        }
        if(count==0){
            System.out.println("No");
        }else{
            System.out.println("Yes");
            for(int i = 0;i<count;i++){
                System.out.print(a[i]);
                if(i!=count-1){
                    System.out.print(" ");
                }
            }
        }
        input.close();
    }
}

💻 代码B:

import java.util.*;
import java.math.BigInteger;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String s = input.next();
        BigInteger num = new BigInteger(s);
        boolean f1 = num.mod(BigInteger.valueOf(3)) == BigInteger.ZERO;
        boolean f2 = num.mod(BigInteger.valueOf(5)) == BigInteger.ZERO;
        boolean f3 = num.mod(BigInteger.valueOf(8)) == BigInteger.ZERO;
        boolean f4 = num.mod(BigInteger.valueOf(11)) == BigInteger.ZERO;
        if (f1 || f2 || f3 || f4){
            System.out.println("Yes");
        }else{
            System.out.println("No");
        }
        if (f1) System.out.print(3 + " ");
        if (f2) System.out.print(5 + " ");
        if (f3) System.out.print(8 + " ");
        if (f4) System.out.print(11 + " ");
        input.close();
    }
}

📚 总结:

知之甚多,知之甚少。越来越觉得自己有许多东西要慢慢去学习,还是要不断练习,自己才能有点提高。觉得牛客、力扣上的简单题自己都要想好久,对算法的学习之路还是要不断提高,目前连门都没有找到呀!!!!

### 牛客 NC200369 四舍五入 解题思路 对于给定的小字符串,需要按照指定的次 `t` 进行四舍五入操作。每次四舍五入都是基于当前最右边的一位小来决定是否进位。 #### 思路分析 1. **初始化处理** - 首先读取输入据并解析成可操作的形式。 - 将原始分转换为字符列表以便逐位修改[^2]。 2. **核心逻辑** - 对于每一次四舍五入: - 如果当前位置小于等于4,则直接截断后续部分; - 若大于等于5则向前一位加一,并继续检查前一位是否会再次触发进位直到不再发生为止。 - 更新剩余需处理的有效位器 `t`,当其减至零时停止循环。 3. **特殊情况考虑** - 当所有有效字都被处理完毕但仍存在未完成的四舍五入需求时,在结果前面补上相应量的&#39;1&#39;。 #### 代码实现 以下是 Python 实现: ```python def round_number(n, t, num_str): # 转换为list方便操作 nums = list(num_str) dot_index = nums.index(&#39;.&#39;) start_pos = dot_index + min(t, len(nums) - 1) while t > 0 and &#39;.&#39; not in str(start_pos): current_digit = int(nums[start_pos]) if current_digit >= 5: carry = True for i in range(start_pos - 1, -1, -1): if nums[i].isdigit(): next_digit = (int(nums[i]) + 1) % 10 if next_digit != 0 or i == 0: carry = False nums[i] = str(next_digit) break if carry: nums.insert(0, &#39;1&#39;) del nums[start_pos:] t -= 1 try: start_pos = max(dot_index + min(t, len(nums) - dot_index - 1), 0) except ValueError as e: pass result = &#39;&#39;.join([str(x) for x in nums]).rstrip(&#39;0&#39;).rstrip(&#39;.&#39;) or "0" return result if __name__ == "__main__": n, t = map(int, input().split()) initial_score = input() print(round_number(n, t, initial_score)) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值