• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Niro Einteson
文可提笔安天下 武可上马定乾坤
博客园    首页    新随笔    联系   管理    订阅  订阅

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 }
posted @ 2019-12-13 22:52  Nirogo  阅读(246)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3