洛谷OJ-P1036 选数 题解(递归DFS)

题目描述.png

解析:这一题的核心为素数判断以及罗列出n个数中选k个数的所有情况。在选数这一过程中使用深搜递归的思路。


先用数组存储数据,然后用dfs递归函数遍历所有情况。

先看代码:

void dfs(int pos, int sum, int choose_num)
{
    if(pos == n || choose_num == k)
    {
        if(choose_num == k && isprime(sum))
        {
            total++;
        }
        return ;
    }
    dfs(pos+1, sum + vec[pos], choose_num+1);
    dfs(pos+1, sum, choose_num);
    return ;
}

其中pos代表目前在数组中的位置;sum代表当前已选数的总和;choose_num代表已选数的个数;n、k和vec是全局变量,记录数组的长度,需要选取的总数以及目标数组。

对于每个数有两种选择的方法
1.选择当前位置的数,继续向下搜索。
2.不选择当前位置的数,继续向下搜索。

当已经选满了k个数或已经遍历完整个数组时,停止dfs。并判断这次选择是否合法(所选数个数是否为k以及所选数总和是否为素数)

整体代码如下

#include 
using namespace std;
int n,k;
int total = 0;
vector vec;

bool isprime(int n)
{
    if(n == 1)
    {
        return 0;
    }
    for(int i = 2 ; i <= sqrt(n) ; i++)
    {
        if(n % i == 0)
        {
            return 0;
        }
    }
    return 1;
}

void dfs(int pos, int sum, int choose_num)
{
    if(pos == n || choose_num == k)
    {
        if(choose_num == k && isprime(sum))
        {
            total++;
        }
        return ;
    }
    dfs(pos+1, sum + vec[pos], choose_num+1);
    dfs(pos+1, sum, choose_num);
    return ;
}

int main()
{
    cin>>n>>k;
    for(int i = 0 ; i < n ; i++)
    {
        int item;
        cin>>item;
        vec.push_back(item);
    }
    dfs(0,0,0);
    cout<

你可能感兴趣的:(洛谷OJ-P1036 选数 题解(递归DFS))