ACM基础题——小刘认亲

1、题目描述

小刘是个儿孙满堂的1所有的质数都是他的子女,除了他的子女外,他还有许多孙子,小刘的孙子都是合数如果一个合数由两个质数相乘而得,那么这个合数就是小刘的直系孙子。小刘年事已高,忘记了哪些是他的直系孙子了,现在,给你一系列自然数,判断它们是否是小刘的直系孙子

抓重点

最终要求:判断给定的自然数是否是小刘的直系子孙
给定条件:

  1. 小刘是一个儿孙满堂的1,所以给定的自然数中不可能再出现1
  2. 所有的质数都是他的子女,质数:只能被1和该数本身整除的数
  3. 孙子是合数,合数:除了1和该数本身还能被其他数整除的数,如果一个合数由两个质数相乘而得那么就是小刘的直系子孙。

输入

第一行一个正整数T,表示需要判断的自然数数量接下来T行,
每行一个要判断的自然数

输出

共T行,依次对于输入中给出的自然数,判断是否为小刘的直系孙子,是则输出Yes,否则输出No

演示

输入样例
4
3
4
6
12

输出样例
No
Yes
Yes
No

代码实现

import java.util.Scanner;

public class Main {
    private static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        int length = scanner.nextInt();//输入数的个数
        int[] number = new int[length];//使用数组存放输入的数
        String[] result = new String[length];//使用字符串数组存放结果

        for(int i = 0; i < length; i++){//遍历输入
            number[i] = scanner.nextInt();
        }

        for(int i = 0; i < length; i++){//遍历number中的数据
            int value = number[i];//拿到数组中的数据
            boolean flag = false;//设定一个标志位,方便结果的存放
            if(!isPro(value)){//判断输入的数据是否是合数,如果不是合数就不是小刘的子孙
                for(int j = 2; j < value; j++){ //遍历该数的子元素,
                
                    int temp = value / j; //利用整除的方式得到另一个子元素
                    //判断两个子元素是否都是质数,并且两个子元素相乘是否是输入的那个数
                    if(isPro(j) && temp * j == value && isPro(temp)){
                        flag = true;//修改标志位
                        //给value重新赋值,以此方法来控制遍历子元素的循环停止
                        value = value % j;
                    }
                }
                result[i] = flag ? "Yes" : "No"; //利用标志位来存放结果
            }else{
                result[i] = "No";//如果输入的数不是合数就直接不是小刘的子孙
            }
        }

		//遍历输出结果
        for(int i = 0; i < length; i++){
            System.out.println(result[i]);
        }
    }

	//判断是否是质数,否则就是合数
    private static boolean isPro(int n){
    	//使用开根号的形式判断素数,能减少很多次运行,大大的节约了程序的运行成本
        for(int i = 2; i <= Math.sqrt(n); i++){ 
            if(n % i == 0) return false;
        }
        return true;
    }
}

总结

这道题目是ACM中的基础题,很简单但是很有意思。
我个人觉得我这段代码写的还是不错的,有点小开心,嘿嘿!

for(int j = 2; j < value; j++){ //遍历该数的子元素,     
      int temp = value / j; //利用整除的方式得到另一个子元素
      //判断两个子元素是否都是质数,并且两个子元素相乘是否是输入的那个数
      if(isPro(j) && temp * j == value && isPro(temp)){
             flag = true;//修改标志位
             //给value重新赋值,以此方法来控制遍历子元素的循环停止
             value = value % j;
       }
}

但是有点不足之处,在循环的时候,无论是质数还是合数,都会循环到,所以还是做了不必要的运行到,如果能直接运行质数的话,运行的时间又会减少大半。
不断的改造不断的优化,这不就是代码的魅力所在吗?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值