P1036 选数

P1036 选数

题目描述
已知 nn 个整数 x1,x2,…,xn
,以及11个整数kk(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)

x_1,x_2,…,x_n (1<=Xi<=5000000)

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

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

 1 解法:
 2 
 3 #include<bits/stdc++.h>
 4 using namespace std;
 5 int data[21];
 6 int book[21];
 7 int n,k;
 8 int Sum=0;//和 为 素数的个数
 9 int sum=0;
10 void dfs(int cnt,int start){//两个参数,一个 用来 记录 选了多少个数字了cnt,另一个 start是每次搜索新开始的索引,
11     if(cnt>k) return ;//超过了统计的个数,返回
12     if(cnt==k){
13         for(int i=2;i<=sqrt(sum);i++){//检查是否是素数
14             if(sum%i==0){
15                 return ;
16             }
17         }
18         Sum++;//是素数, 个数+1
19         return ;
20     }
21     for(int i=start;i<n;i++){//主要
22         if(book[i]==0){
23             book[i]=1;//标记 被选上了
24             sum+=data[i];//sum加上这个数据
25             cnt++;//选择的个数加1
26             dfs(cnt,i+1);//这样写,cnt,sum不用再恢复了,就算不满足,仍然是原来的数
27             cnt--;//恢复 选择的个数  -1
28             book[i]=0;//取消被选的这个数字
29             sum-=data[i];
30         }
31     }
32     return ;
33 }
34 int main()
35 {
36     /*思路:不知道数据 Xi都是一样的会怎样
37         1:用data数组存数据,book 数组 标记 是否 选中
38         2:两个参数,一个 用来 记录 选了多少个数字了cnt,
39         3:另一个 start是每次搜索新开始的索引,
40         4:递归 回溯 求解,
41 */
42     cin>>n>>k;
43     for(int i=0;i<n;i++){
44         cin>>data[i];
45         book[i]=0;
46     }
47     dfs(0,0);//已经选了0个,从0开始的遍历
48     cout<<Sum<<endl;
49     return 0;
50 }

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int data[21];
 4 int n,k;
 5 int Sum=0;//和 为 素数的个数
 6 void dfs(int cnt,int start,int sum){//两个参数,一个 用来 记录 选了多少个数字了cnt,另一个 start是每次搜索新开始的索引,
 7     if(cnt>k) return ;//超过了统计的个数,返回
 8     if(cnt==k){
 9         for(int i=2;i<=sqrt(sum);i++){//检查是否是素数
10             if(sum%i==0){
11                 return ;
12             }
13         }
14         Sum++;//是素数, 个数+1
15         return ;
16     }//从新的地方开始,
17     for(int i=start;i<n;i++){//主要从新的索引 开始;不选择标记  因为  都是临时性的遍历,副本数据并没有更新,只是dfs传入的数据遍历
18         dfs(cnt+1,i+1,sum+data[i]);//这样写,cnt,sum不用再恢复了,就算不满足,仍然是原来的数
19     }
20     return ;
21 }
22 int main()
23 {
24     /*思路:不知道数据 Xi都是一样的会怎样
25         1:用data数组存数据,book 数组 标记 是否 选中
26         2:两个参数,一个 用来 记录 选了多少个数字了cnt,
27         3:另一个 start是每次搜索新开始的索引,
28         4:递归 回溯 求解,
29 */
30     cin>>n>>k;
31     for(int i=0;i<n;i++){
32         cin>>data[i];
33     }
34     dfs(0,0,0);//已经选了0个,从0开始的遍历,sum=0
35     cout<<Sum<<endl;
36     return 0;
37 }
上一篇:c#继承中的函数调用


下一篇:P1036 选数