夕拾算法进阶篇:8)组合+判断素数(dfs)

来源:互联网 发布:唐七公子知乎 编辑:程序博客网 时间:2024/06/05 21:02
题目描述
已知 n 个整数b1,b2,…,bn以及一个整数 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<n) 
第二行n个整数:x1,x2,…,xn (1<=xi<=5000000) 

输出
一个整数(满足条件的方案数)。 

样例输入
4 3
3 7 12 19
样例输出

1


这个题上上一个题7)组合的输出(dfs)是一样的。N个元素里面选M个元素的基本思路是防止重复选。比如上面的3 7 12 选出来后,7 3 12就不能在选了。这个也非常好实现,只要保存元素数组下标是有序的,就可以保证该序列包含的元素只出现一次。


可以直接使用之前的代码进行实现(如果要输出上面题目给出的完整格式,并升序,可以在main函数中直接对元素排序后得到),代码如下

#include <iostream>#include <cstdio>#include <algorithm>using namespace std;int a[25]; //保存输入值的下标 int v[25]; //保存输入的值 int k,n,c=0;bool isPrime(int num){for(int i=2;i*i<=num;i++){if(num%i==0){return false;}}return true;}// cur为当前的层次  void Dfs(int cur){      for(int i=1;i<=n;i++){          if(cur<=1||a[cur-1]<i){//当前是第一层或者下标序列升序               a[cur]=i; //保存数组下标              if(cur==k){ //到底第k层,int sum=0,index;                   for(int j=1;j<=k;j++){                      index=a[j];sum+=v[index];                  }  if(isPrime(sum)) c++; //符合条件                 continue; //剪枝                }              Dfs(cur+1);               }      }  }  int main(){scanf("%d%d",&n,&k);for(int i=1;i<=n;i++){scanf("%d",v+i);}Dfs(1); //从第一层开始 printf("%d\n",c);return 0;}

题目来源:http://www.codeup.cn/problem.php?cid=100000608&pid=2

0 0
原创粉丝点击