洛谷题解:P1036 [NOIP2002 普及组] 选数(dfs)

洛谷题解:P1036 [NOIP2002 普及组] 选数

题目:

已知 n 个整数 x1,x2,…,xn,以及1个整数k(k<n)。从n个整数中任选k个整数相加,可分别得到一系列的和。例如当n=4,k=3,4个整数分别为3,7,12,19时,可得全部的组合与它们的和为:

3+7+12=22

3+7+19=29

7+12+19=38

3+12+19=34

现在,要求你计算出和为素数共有多少种。

例如上例,只有一种的和为素数:3+7+19=29。

输入格式:

键盘输入,格式为:

n,k(1≤n≤20,k<n1)

x1,x2,…,xn(1≤xi≤5000000)

输出格式:

屏幕输出,格式为: 1个整数(满足条件的种数)。

扫描二维码关注公众号,回复: 12916365 查看本文章

样例:

输入:

4 3
3 7 12 19

输出:

1

分析:

这道题需要通过dfs去遍历三个不同元素的组合,最后再用单个的普通筛法筛取素数。

下面解释一下dfs搜索的方法。

一个最多20个数,每一次循环为1或0的循环,即表示这个数是否被选择。

搜索停止的条件就是元素满足三个的时候,即return;我忘了return;debug了近半个多小时…血亏

然后循环次数达到元素个数的时候也停止搜索。

筛法就是普通筛法,数据组数很少。

代码:

#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>

using namespace std;

int n,k;
long long a[100];
long long sum[100];
long long num = 0;
long long Sum = 0;
long long judge = 1;
long long jie = 1;
int q = 0;

void dfs(int now)
{
    
    
    if(num == k)
    {
    
    
        sum[q++] = Sum;
        return;
    }
    if(now == n)
    {
    
    
        return;
    }
    for(int i = 1;i >= 0;i--)
    {
    
    
        if(i)
        {
    
    
            Sum += a[now];
            num++;
            dfs(now + 1);
            Sum -= a[now];
            num--;
        }
        else
        {
    
    
            dfs(now + 1);
        }
    }
}

bool isprime(long long x)
{
    
    
    for(long long i = 2;i <= sqrt(x);i++)
    {
    
    
        if(x % i == 0)
        {
    
    
            return false;
        }
    }
    return true;
}

int main()
{
    
    
    cin>>n>>k;
    int temp = n;
    int temp2 = k;
    int ans = 0;
    for(int i = 0;i < k;i++)
    {
    
    
        judge = judge * temp--;
        jie = jie * temp2--;
    }
    judge = judge / jie;
    memset(a,0,sizeof(a));
    memset(sum,0,sizeof(sum));
    for(int i = 0;i < n;i++)
    {
    
    
        cin>>a[i];
    }
    dfs(0);
    for(int i = 0;i < q;i++)
    {
    
    
        if(isprime(sum[i]))
        {
    
    
            ans++;
        }
    }
    cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_46052886/article/details/113525621