百度松果菁英班作业整理(第一期)

本期的题目比较简单,最后两题稍微复杂,但是主题思路也不难,大家可以一起练习。

孪生质数

在质数中,若两个质数之差为2,我们称之为孪生质数,例如(3、5)
(5、7),输入2个正整数,判断他是不是孪生质数,输出YES或者NO。

import java.util.Scanner;
import java.util.*;

class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        int b = sc.nextInt();
        if (prime_judge(a) && prime_judge(b) && Math.abs((a-b))==2 ) {
            System.out.printf("YES");
        }
        else {
            System.out.printf("NO");
        }
    }
    public static boolean prime_judge(int m){
        if(m < 2){
            return false;
        }
        for (int i = 2; i <= Math.sqrt(m); i++) {
            if (m % i == 0) {
                return false;
            }
        }
        return true;
    }
}

这里可以稍微复习一下质数判断的算法,其他的没有什么好讲的,简单的条件判断。

自守数1

输入正整数N(N10),判断该数是否为自守数输出YES或者N0。当且仅当一个数的平方以与该数相同的数字结尾时,该数称为自守数。

import java.util.Scanner;
import java.util.*;

class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        if(judge_conservative_num(a)){
            System.out.printf("YES");
        }
        else System.out.printf("NO");
    }

    public static boolean judge_conservative_num(int m){
        boolean res = true;
        if ((m*m) % 10 == m && m<10) {
            res = true;
        }
        else res = false;
        return res;
    }
}

卡罗尔数

卡罗尔数是其值满足4n-2(n+1)-1的整数(n为正整数)。输入正整数N判断它是不是卡罗尔数,输出YES或者NO。

import java.util.Scanner;
import java.util.*;

class Main {

   public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        sc.close();
        boolean isCarolNumber = false;

        for (int n = 1; ; n++) {
            int carolNumber = 4 * n - 2 * (n + 1) - 1;
            if (carolNumber == a) {
                isCarolNumber = true;
                break;
            }
            if (carolNumber > a) {
                break;
            }
        }

        if (isCarolNumber) {
            System.out.println("YES");
        } else {
            System.out.println("NO");
        }
    }
}

这是最基础的算法,但是我觉得应该还是有更优化的算法的,毕竟一个一个遍历确实太慢了。

输入正整数N,请在1!,2!,3!. N!中查找尾数为零的数,统计这样的数字的个数并输出。
1722497658749.png

尾数为0

import java.util.Scanner;
import java.util.*;

class Main {

   public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        int count = 0;
        for (int i = 1; i <= a; i++) {
            if(fac(i)%10 == 0) count++;
        }
        System.out.println(count);
    }

    public static int fac(int m){
        int res = 0;
        if (m==0 || m==1) res=1;
        else if (m >= 2) res = m * fac(m-1);
        return res;
    }

}

数组最大公约数

给定一个由N个正整数组成的数组,求所有数组元素的最大公约数。

import java.util.Scanner;
import java.util.*;

class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int []arr = new int[N];
        for (int i = 0; i <N ; i++) {
            arr[i] = sc.nextInt();
        }
        sc.close();
        int res = 0;
        res = Greatest_common_divisor(arr);
        System.out.println(res);
    }
    public static int Greatest_common_divisor(int a,int b){
        if (b == 0) {
            return a;
        }
        return Greatest_common_divisor(b, a % b);
    }
    public static int Greatest_common_divisor(int []numbers){
        int result = numbers[0];
        for (int i = 1; i < numbers.length; i++) {
            result = Greatest_common_divisor(result, numbers[i]);
            // 如果在此过程中发现最大公约数为1,可以直接返回1
            if (result == 1) {
                return 1;
            }
        }
        return result;
    }
}

这里复习一下辗转相除法求两个数的最大公约数,也是用一个递归的思想完成:不断将较小的数和两数相除的余数作为新的参数传递,直到余数为0,此时返回的数即为最大公约数。
然后就是用了一个方法的重载,实现一组数求最大公约数。

指定集合

某数组含有N个元素,输出那些数字来自集合{4,5,6}的元素,按原序。没有就输出-1。

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        List<Integer> result = new ArrayList<>();

        int N = scanner.nextInt();
        int[] array = new int[N];
        for (int i = 0; i < N; i++) {
            array[i] = scanner.nextInt();
        }

        // 遍历数组,检查每个元素是否属于集合 {4, 5, 6}
        for (int num : array) {
            if (num == 4 || num == 5 || num == 6) {
                result.add(num);
            }
        }

        // 如果没有符合条件的元素,输出 -1
        if (result.isEmpty()) {
            System.out.println(-1);
        } else {
            // 按原序输出符合条件的元素
            for (int num : result) {
                System.out.print(num + " ");
            }
        }

        scanner.close();
    }
}

这里用到了一个动态列表的创建,可以参考一下我之前的这篇文章——简易测井资料处理分析系统,里面有类似的讲解,我们暂时不展开讲,后面也会有单独的文章发出来。

阶乘数

输入正整数N,找出它是否是一个等于其他数的阶乘值的数,输出YES或者NO。

import java.util.Scanner;
import java.util.*;

class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int count = 0;
        for (int i = 0; i <= N; i++) {
            if (N == fac(i)){
                count++;
                break;
            }
        }
        if(count!=0) System.out.println("YES");
        else System.out.println("NO");
    }
    public static int fac(int m){
        int res = 0;
        if (m==0 || m==1) res=1;
        else if (m >= 2) res = m * fac(m-1);
        return res;
    }
}

自守数2

输入正整数N,检查该数是否为自守数输出YES或者N0。当且仅当一个数的平方以与该数相同的数字结尾时,该数称为自守数。

import java.util.Scanner;
import java.util.*;

class Main {

public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        String n = Integer.toString(a);
        int digits = n.length();
        if(jcn(a,digits)){
            System.out.printf("YES");
        }
        else System.out.printf("NO");
    }

    public static boolean jcn(int m,int digits){
        boolean res = true;
        if ((m*m) % (Math.pow(10,digits)) == m ) {
            res = true;
        }
        else res = false;
        return res;
    }
}

这里注意反复读题,不要有思维惯性,认真弄懂题目要求之后再开始写代码。

N的零

输入正整数N,将N的所有零转换为5。没有就原样输出。不考虑不合理的输入等特殊情况。

import java.util.Scanner;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        sc.close();

        String n = Integer.toString(a);
        StringBuilder result = new StringBuilder();

        for (int i = 0; i < n.length(); i++) {
            char digit = n.charAt(i);
            if (digit == '0') {
                result.append('5');
            } else {
                result.append(digit);
            }
        }

        int modifiedNumber = Integer.parseInt(result.toString());
        System.out.println(modifiedNumber);
    }
}

这里也是提供一种思路嗷,刚开始我一直拿模运算和除运算想判断0和5,发现有点复杂,后来干脆偷了个懒直接用字符判断了,确实也简单许多。
这里我们先将读取的正整数用Integer.toString()转换成字符型,然后我们对StringBuilder这个类进行实例化:
StringBuilder result = new StringBuilder();
这是 Java 中的一个类,表示一个可变的字符序列。与 String 类不同,String 类是不可变的(即一旦创建,其值不能被改变),**而 StringBuilder 允许你在创建后通过追加、插入或删除字符和子字符串来修改其内容。我们后续也是这么做的。
然后我们进行了一个遍历+索引,其中
charAt()**是 String 类的一个方法,用于返回字符串中指定位置的字符。如果是0就用.append加一个字符5到result这个可变字符序列后面,如果不是0就把这个字符放到result这个可变字符序列后面。
最后我们用int modifiedNumber = Integer.parseInt(result.toString());
将字符转换成整型。

最大非递减数字

输入正整数N,找到小于或等于它的最大数字,并且其数字从高位到低位是非递减的顺序。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        scanner.close();

        int result = findLargestNumber(N);
        System.out.println(result);
    }

    public static int findLargestNumber(int N) {
        char[] digits = Integer.toString(N).toCharArray();

        int i = 0;
        // 找到第一个不满足非递减顺序的位置
        while (i < digits.length - 1 && digits[i] <= digits[i + 1]) {
            i++;
        }

        // 如果找到了这样的位置
        if (i < digits.length - 1) {
            // 将该位置的数字减1
            digits[i]--;
            // 将该位置之后的所有数字设置为9
            for (int j = i + 1; j < digits.length; j++) {
                digits[j] = '9';
            }
        }

        // 将字符数组转换回整数
        return Integer.parseInt(new String(digits));
    }
}

1722497589102.png
这个题还是稍微有点意思的,要弄清楚——从高位到低位是非递减的顺序是什么意思。比如299、399甚至999都满足,还有157、137、138、135、188、177等等等等,但是要满足最大的,那就要往“9”这个数字上靠啦。
我们得到一个数,然后用 char[] digits = Integer.toString(N).toCharArray();这个跟上一题的很像,但是多了一个’.toCharArray()'。toCharArray()是 String 类的一个方法,用于将字符串转换为字符数组。例如,如果字符串是 “1234”,那么 toCharArray() 将返回字符数组 {‘1’, ‘2’, ‘3’, ‘4’}。
那么我们得到类似的效果后接下来就是重点了:

while (i < digits.length - 1 && digits[i] <= digits[i + 1]) {
            i++;
        }

怎么理解呢?比如我们输入513,很明显他是不满足非递减顺序数字的,我们就要找到它是在哪个位置上不满足,i=0时他就会判断5是>1的,所以结束循环,然后此时i仍然是0,不执行i++。

if (i < digits.length - 1) {
            // 将该位置的数字减1
            digits[i]--;
            // 将该位置之后的所有数字设置为9
            for (int j = i + 1; j < digits.length; j++) {
                digits[j] = '9';
            }
        }

那么我们就将digits的0位置数字-1,就变成4,其他位置都变成9,也就是499,就找到最大的非递减顺序数字了!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值