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

3+7+12=223+7+12=22

3+7+19=293+7+19=29

7+12+19=387+12+19=38

3+12+19=343+12+19=34 。 

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

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

输入格式:

 

键盘输入,格式为:

n,kn,k ( 1≤n≤20,k<n1n20,k<n )

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

 

输出格式:

 

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

 

输入样例#1:

  1. 4 3
  2. 3 7 12 19
输出样例#1:

  1. 1

 

  感觉就是一个dfs的模板题,加上判断素数就可以了,整个题的数据量也不大,没有什么特别说明的。

  附上代码(已AC)

  1. 1 #include <iostream>
  2. 2 using namespace std;
  3. 3
  4. 4 int n, k, x[21]={0};
  5. 5 int sum=0, ans=0;
  6. 6
  7. 7 bool judge(int t){ #判断是否是素数
  8. 8 if(t==2) return true;
  9. 9 for(int i=2;i<t/2;i++){
  10. 10 if(t%i==0) return false;
  11. 11 }
  12. 12 return true;
  13. 13 }
  14. 14
  15. 15 void dfs(int count, int pos){ #count是当前有几个数被计算了,pos是他们的位置
  16. 16 if(count > k){
  17. 17 if(judge(sum)){
  18. 18 ans++;
  19. 19 }
  20. 20 return; #回溯
  21. 21 }
    22 else{
  22. 23 for(int i=pos+1;i<=n;i++){
  23. 24 sum += x[i];
  24. 25 dfs(count+1, i);
  25. 26 sum -= x[i];
  26. 27 }
  27. 28 }
  28. 29 }
  29. 30
  30. 31 int main(){
  31. 32 cin >> n >> k;
  32. 33 for(int i=1;i<=n;i++) cin >> x[i];
  33. 34 dfs(1,0);
  34. 35 cout << ans;
  35. 36 return 0;
  36. 37 }

 


 

  1. 1 void dfs()//参数用来表示状态
  2. 2 {
  3. 3 if(到达终点状态)
  4. 4 {
  5. 5 ...//根据题意添加
  6. 6 return;
  7. 7 }
  8. 8 if(越界或者是不合法状态)
  9. 9 return;
  10. 10 if(特殊状态)//剪枝
  11. 11 return ;
  12. 12 for(扩展方式)
  13. 13 {
  14. 14 if(扩展方式所达到状态合法)
  15. 15 {
  16. 16 修改操作;//根据题意来添加
  17. 17 标记;
  18. 18 dfs();
  19. 19 (还原标记);
  20. 20 //是否还原标记根据题意
  21. 21 //如果加上(还原标记)就是 回溯法
  22. 22 }
  23. 23
  24. 24 }
  25. 25 }

 

版权声明:本文为jyroy原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/jyroy/p/9528888.html