题解 | #kotori和素因子#
kotori和素因子
https://www.nowcoder.com/practice/7b1c858a3e7a41ed8364178979eaae67
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.StreamTokenizer; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Scanner; import java.util.Set; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { //默认不存在栈深为n(正整数个数)的路径 public static int min = Integer.MAX_VALUE; //记录每个数的素因子集合 private static final List<List<Integer>> list = new ArrayList<>(); //用于标记访问过的素因子(一条路径上) private static final Set<Integer> set = new HashSet<>(); //判素数模板 public static boolean isPrime(int num) { if (num == 1) return false; for (int i = 2; i <= Math.sqrt(num); i++) { if (num % i == 0) return false; } return true; } public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StreamTokenizer st = new StreamTokenizer(br); st.nextToken(); int n = (int) st.nval; for (int i = 0; i < n; i++) { st.nextToken(); int num = (int) st.nval; //存储每个数的素因子集合 list.add(getPrimes(num)); } dfs(0, 0); System.out.println(min == Integer.MAX_VALUE ? -1 : min); } private static void dfs(int depth, int sum) { //在每个素因子集合中选出一个组成一条包含不同素因子的路径,就求一次和 if (depth == list.size()) { min = Math.min(min, sum); return; } int size = list.get(depth).size(); for (int i = 0; i < size; i++) { int e = list.get(depth).get(i); if (set.contains(e)) continue; set.add(e); dfs(depth + 1, sum + e); //下层递归完,返回上一层,将已经标记过的移出路径 set.remove(e); } } //获取整数的素因子集合 private static List<Integer> getPrimes(int num) { List<Integer> p = new ArrayList<>(); for (int i = 1; i < Math.sqrt(num); i++) { if (num % i == 0) { if (isPrime(i)) p.add(i); if (isPrime(num / i)) p.add(num / i); } //有平方根的整数的平方根项要单独判断,否则会出现9 {3,3} 这样重复的素因子,极大降低性能。 double c = Math.sqrt(num); if (Math.floor(c) == c) { if (isPrime((int) c)) p.add((int) c); } } return p; } }