首页 > 试题广场 >

kotori和素因子

[编程题]kotori和素因子
  • 热度指数:6616 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt}kotori 拿到 n互不相同的正整数 a_1,a_2,\dots,a_n。她要从每个 a_i 中选出一个素因子 p_i,要求所有选出的素因子两两不同,即 p_i\neq p_j\;(i\neq j)

\hspace{15pt}若无法满足要求输出 -1;否则输出所有选出的素因子之和 \displaystyle\sum_{i=1}^{n}p_i 的最小可能值。

输入描述:
\hspace{15pt}第一行输入整数 n\left(1\leqq n\leqq 10\right)
\hspace{15pt}第二行输入 n 个两两不同的整数 a_i\left(2\leqq a_i\leqq 1000\right)


输出描述:
\hspace{15pt}若存在合法选取方案,输出最小可能和;否则输出 -1
示例1

输入

4
12 15 28 22

输出

17

说明

可取素因子 [3,5,7,2],和为 17;任意合法方案的和都不小于 17
示例2

输入

5
4 5 6 7 8

输出

-1

备注:

import java.util.*;
public class Main {
//定义存放的list的list(因为list中数组长度可变),用来存放每个数的素因子
    static List<List<Integer>> list = new ArrayList<List<Integer>>();
    static int deepth = 0;//深度,也就是正整数的个数;
    static int minRes = 10000;//返回的结果
    static int[] vis = new int[1000];//因为每个访问的数都不重复,所以vis[i]指i是否被访问过
    static int sum = 0;//搜索时的和
    static boolean flag = false; //flag为1说明已经找到了最小值(遍历到了最底层(说明每个数都有素因子,只要有一个数没有,则无法递归到最底层))
//先找到每个数的素因子,然后再深度搜索满足条件的最小值,若不存在,则输出-1
//判断是否为素数
    public static boolean isSu(int n) {
        if (n == 1) {
            return false;
        }
        //从2开始到根号n之间,只要找到n可以除尽的数,说明n有其他因子,则n不是素数
        for (int i = 2; i <= Math.sqrt(n); i++) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }

//找素因子,n为输入的数,x为在list中存放的位置(第几行)
    public static void prime(int n, int x) {
        List<Integer> tempList = new ArrayList<Integer>();
        for (int i = 1; i <= Math.sqrt(n); i++) {
            if (n % i == 0) {
                if (isSu(i)) {
                    tempList.add(i); //满足素数,则存入
                }
                //还要存对应的另外一个因子(因为只遍历到根号n),前提是另外一个因子和此因子不相等,且也为素数
                if (i * i != n && isSu(n / i)) {
                    tempList.add(n / i);
                }
            }
        }
        list.add(tempList);
    }

//深度搜索:y为第几层
    public static void dfs(int y) {
        if (y == deepth) { //如果遍历深度到最底层,退出,只能往回找了
            flag = true;//此时说明每一层都有素因子,合法的,一定会有最小值
            minRes = Math.min(minRes, sum);
            return;
        }
        for (int i = 0; i < list.get(y).size(); i++) {
            if (vis[list.get(y).get(i)] == 0) { //说明没有被访问
                sum += list.get(y).get(i);
                vis[list.get(y).get(i)] = 1;//标记为已访问
                dfs(y + 1);//开始遍历下一层;
                vis[list.get(y).get(i)] = 0;//遍历后回溯要先将该点标记为未访问
                sum -= list.get(y).get(i);//标为未读后要将该点的值去掉
            }
        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        deepth = Integer.parseInt(in.nextLine());
        String[] res = in.nextLine().split(" ");
        //获取每一个数的素因子,放入list中
        for (int i = 0; i < deepth; i++) {
            prime(Integer.parseInt(res[i]), i);
        }
        //开始从第一层深度搜索
        dfs(0);
        //输出结果
        if (!flag) {
            System.out.println("-1");
        } else {
            System.out.println(minRes);
        }
    }
}
发表于 2022-04-16 21:33:02 回复(0)

问题信息

难度:
2条回答 3135浏览

热门推荐

通过挑战的用户

查看代码
kotori和素因子