洛谷:P1036:选数

题目描述

已知 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:
4 3
3 7 12 19
输出样例#1:
1

题解:

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

  附上代码(已AC)

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

dfs模板(伪代码):

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