每日OJ_牛客_kotori和素因子_DFS_C++_Java

目录

牛客_kotori和素因子_DFS

题目解析

C++代码

Java代码


牛客_kotori和素因子_DFS

kotori和素因子

描述:

kotori拿到了一些正整数。她决定从每个正整数取出一个素因子。但是,kotori有强迫症,她不允许两个不同的正整数取出相同的素因子。

她想知道,最终所有取出的数的和的最小值是多少?

注:若 a mod k==0,则称 k 是 a 的因子。若一个数有且仅有两个因子,则称其是素数。显然1只有一个因子,不是素数。

输入描述:

第一行一个正整数 n ,代表kotori拿到正整数的个数。 第二行共有 n 个数 ai,表示每个正整数的值。 保证不存在两个相等的正整数。

1≤n≤10

2≤ai≤1000

输出描述:

一个正整数,代表取出的素因子之和的最小值。若不存在合法的取法,则输出-1。


题目解析

这道题目要求为数组中的每个数选择一个互不重复的质因数,使得这些质因数的和最小。通过回溯法(DFS)枚举所有可能的质因数组合,并在过程中剪枝和记录最小值,最终可以得到答案。如果没有合法组合,则返回-1。这是一种典型的组合优化问题,适合用深度优先搜索来解决。

C++代码

cpp 复制代码
#include <iostream>
#include <set>
#include <vector>
#include <cmath>
using namespace std;

int ret = 0x3f3f3f3f;
bool use[1007]; // 记录路径中⽤了哪些值
int pathSum; // 记录当前路径中所有元素的和
int n = 0;

bool is_prime(int n)
{
    int i = 0;
    for (i = 2; i <= sqrt(n); i++)
    {
        if (0 == n % i)
            return false;
    }
    return true;
}

void dfs(vector<int>& a, int pos)
{
    if(pos == n)
    {
        ret = min(ret, pathSum);
        return;
    }
    
    for(int i = 2; i <= a[pos]; i++)
    {
        if(a[pos] % i == 0 && is_prime(i) && !use[i])
        {
            pathSum += i;
            use[i] = true;
            dfs(a, pos + 1);
                
            pathSum -= i;
            use[i] = false;
        }
    }
}

int main()
{
    cin >> n;
    vector<int> a(n);
    for(int i = 0; i < n; ++i)
    {
        cin >> a[i];
    }
    dfs(a, 0);
    if(ret == 0x3f3f3f3f)
        cout << -1 << endl;
    else
        cout << ret;
    return 0;
}

Java代码

cpp 复制代码
import java.util.*;
public class Main
{
    public static int n;
    public static int[] arr;
    public static boolean[] use = new boolean[1010]; // 记录路径⾥⾯选了哪些元素
    public static int path; // 记录路径⾥⾯所有元素的和
    public static int ret = 0x3f3f3f3f; // 记录最终结果

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

    public static void dfs(int pos)
    {
        if(pos == n)
        {
            ret = Math.min(ret, path);
            return;
        }

        // 枚举 arr[pos] ⾥⾯所有的素因⼦
        for(int i = 2; i <= arr[pos]; i++)
        {
            if(arr[pos] % i == 0 && !use[i] && isPrim(i))
            {
                path += i;
                use[i] = true;
                dfs(pos + 1);
                // 回溯 - 恢复现场
                use[i] = false;
                path -= i;
            }
        }
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        arr = new int[n];
        for(int i = 0; i < n; i++)
        {
            arr[i] = in.nextInt();
        }

        dfs(0);

        if(ret == 0x3f3f3f3f)
            System.out.println(-1);
        else
            System.out.println(ret);
    }
}
相关推荐
小欣加油2 分钟前
leetcode 174 地下城游戏
c++·算法·leetcode·职场和发展·动态规划
小希smallxi8 分钟前
Java 程序调用 FFmpeg 教程
java·python·ffmpeg
李慕婉学姐11 分钟前
【开题答辩过程】以《基于Java的周边游优选推荐网站的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言
Two_brushes.11 分钟前
Cmake中寻库文件的路径
开发语言·c++·cmake
sali-tec13 分钟前
C# 基于OpenCv的视觉工作流-章11-高斯滤波
图像处理·人工智能·opencv·算法·计算机视觉
菜鸟江多多15 分钟前
【STM32 Rocket-Pi原理图分享】
c语言·stm32·嵌入式硬件·mcu·智能硬件·原理图
良木生香17 分钟前
【C语言进阶】文件操作的相关详解(1):
c语言·数据结构·c++
Larry_Yanan17 分钟前
Qt安卓开发(三)双摄像头内嵌布局
android·开发语言·c++·qt·ui
计算机毕设指导618 分钟前
基于微信小程序民宿预订管理系统【源码文末联系】
java·spring boot·mysql·微信小程序·小程序·tomcat·maven
我命由我1234522 分钟前
Kotlin 开发 - Kotlin Lambda 表达式返回值
android·java·开发语言·java-ee·kotlin·android studio·android-studio