题目描述
已知 n 个整数 x 1 , x 2 , … , x n x_1,x_2,…,x_n x1,x2,…,xn,以及1个整数k( k < n k<n k<n)。从n个整数中任选k个整数相加,可分别得到一系列的和。例如当 n = 4 , k = 3 n=4,k=3 n=4,k=3,4个整数分别为 3 , 7 , 12 , 19 3,7,12,19 3,7,12,19时,可得全部的组合与它们的和为:
3 + 7 + 12 = 22 3+7+12=22 3+7+12=22
3 + 7 + 19 = 29 3+7+19=29 3+7+19=29
7 + 12 + 19 = 38 7+12+19=38 7+12+19=38
3 + 12 + 19 = 34 3+12+19=34 3+12+19=34
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数: 3 + 7 + 19 = 29 3+7+19=29 3+7+19=29。
输入格式
键盘输入,格式为:
n , k n,k n,k( 1 ≤ n ≤ 20 , k < n 1 \le n \le 20,k<n 1≤n≤20,k<n)
x 1 , x 2 , … , x n ( 1 ≤ x i ≤ 5000000 ) x_1,x_2,…,x_n (1 \le x_i \le 5000000) x1,x2,…,xn(1≤xi≤5000000)
输出格式
屏幕输出,格式为: 1个整数(满足条件的种数)。
输入输出样例
输入
4 3
3 7 12 19
输出
1
分析
深度搜索即可,结合代码注释即可理解
AC的C++代码:
#include<iostream>
#include<cmath>
using namespace std;
const int maxn = 21;
int x[maxn];
int n,k,ans; //ans为满足条件的种数
//判断素数
bool isprime(int num){
for(int i=2; i <= sqrt(num); i++)
if(num % i == 0)
return false;
return true;
}
//index当前数的下标,sum为已选择所有数的和,num为已选择数的个数
void DFS(int index, int sum, int num){
if(num == k) //到达边界
if( isprime(sum) ) //是素数
ans++;
for(int i =index; i<=n; i++)
DFS(i+1, sum+x[i], num+1);
}
int main(){
cin>>n>>k;
for(int i = 1; i <= n; i++)
cin >> x[i];
DFS(1,0,0);
cout<<ans;
return 0;
}