本期的题目比较简单,最后两题稍微复杂,但是主题思路也不难,大家可以一起练习。
孪生质数
在质数中,若两个质数之差为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!中查找尾数为零的数,统计这样的数字的个数并输出。
尾数为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));
}
}
这个题还是稍微有点意思的,要弄清楚——从高位到低位是非递减的顺序是什么意思。比如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,就找到最大的非递减顺序数字了!