洛谷: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<n1≤n≤20,k<n )
x1,x2,…,xn(1≤xi≤5000000)x1,x2,…,xn(1≤xi≤5000000)
输出格式:
屏幕输出,格式为: 11 个整数(满足条件的种数)。
输入输出样例
题解:
感觉就是一个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 }