特殊的质数肋骨(dfs)

方法一:枚举

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int min = (int) (1*Math.pow(10,n-1));
        int max = min *10 - 1;
        for (int i = min; i <= max; i++) {
            if(f(i,n)) System.out.println(i);
        }
    }
    private static boolean f(int i,int n) {
        for (int j = 0; j < n; j++) {
            if(isprime(i)){
                i/=10;
                continue;
            }
            return false;
        }
        return true;
    }


    private static boolean isprime(int x) {
        if(x<2) return false;
        int t = (int) Math.sqrt(x);
        for (int i = 2; i <= t; i++) {
            if(x%i == 0) return false;
        }
        return true;
    }
}

这个方法超时了。

方法二:dfs

上面的方法是先列出所有可能,再挨个挨个判断,比如先判断7331、 再判断733、再判断73.......,在列出可能的时候,有很多的数据很显然是没有用的,如果我们反过来,先判断7、再判断73、再判断733....这样进行递归判断,就不需要枚举那么多的数据。


import java.util.Scanner;

public class Main {
    static int n;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        dfs(0,1);
    }
    //x表示前面长度为length-1的数,
    public static void dfs(int x,int length) {   
        if(length>n)   //满足长度时输出
        {
            System.out.println(x);
        }
        else {
            for (int i = 1; i <= 9; i++) {
                if(isprime(x*10+i))
                {
                    dfs(x*10+i, length+1);
                }
            }
        }
    }


    private static boolean isprime(int x) {
        if(x<2) return false;
        int t = (int) Math.sqrt(x);
        for (int i = 2; i <= t; i++) {
            if(x%i == 0) return false;
        }
        return true;
    }
}

三:对方法二的改进

经过分析可知,第一位的数字只能是2、3、5、7,后面的每一位只能是1、3、7、9(2或5结尾的不是质数),我们只需要对这些组合进行判断即可。

import java.util.Scanner;

public class Main {
    static int n;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        int[] a= {2,3,5,7};//第一个数
        for (int i = 0; i < a.length; i++) {
            dfs(a[i],1);
        }
    }

    private static void dfs(int x, int len) {
        if(len == n){
            if(isprime(x)){
                System.out.println(x);
            }
        }
        if(isprime(x)){
            //考虑每种组合
            dfs(x*10+1,len+1);
            dfs(x*10+3,len+1);
            dfs(x*10+7,len+1);
            dfs(x*10+9,len+1);
        }
    }

    private static boolean isprime(int x) {
        if(x<2) return false;
        int t = (int) Math.sqrt(x);
        for (int i = 2; i <= t; i++) {
            if(x%i == 0) return false;
        }
        return true;
    }
}

 

你可能感兴趣的:(刷题)