题目描述
已知 n 个整数 x1,x2,⋯,xn,以及 1 个整数 k(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)。
第二行 n 个整数,分别为 x1,x2,⋯,xn(1≤xi≤5×106)。
输出格式
输出一个整数,表示种类数。
输入输出样例
输入
4 3
3 7 12 19
输出
1
代码
无注释版
#include<bits/stdc++.h>
using namespace std;
int prime(int x){
for(int i=2;i<=sqrt(x);i++){
if(x%i==0) return 0;
}
return 1;
}
int a[22],f[22];
int s,sum;
int n,k;
void dfs(int x,int h){
if(x==k){
if(prime(s)){
sum++;
}
return;
}
for(int i=h;i<=n;i++){
if(f[i]==0){
f[i]=1;
s+=a[i];
dfs(x+1,i+1);
s-=a[i];
f[i]=0;
}
}
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
}
dfs(0,1);
cout<<sum;
}
有注释版
#include<bits/stdc++.h> // 引入标准库,包含常用的C++库
using namespace std; // 使用标准命名空间
// 判断一个数是否为素数
int prime(int x) {
// 如果 x 小于 2,直接返回 false
if (x < 2) return 0;
// 从 2 到 sqrt(x) 遍历,检查是否存在能整除 x 的数
for (int i = 2; i <= sqrt(x); i++) {
if (x % i == 0) return 0; // 如果能被 i 整除,则 x 不是素数
}
return 1; // 否则 x 是素数
}
int a[22], f[22]; // a 数组存储输入的整数,f 数组用于标记数字是否被选择
int s, sum; // s 用来存储当前组合的和,sum 用来存储符合条件的素数和的组合数
int n, k; // n 是整数个数,k 是要选择的整数个数
// 深度优先搜索(DFS)函数,用来遍历所有选择 k 个数的组合
void dfs(int x, int h) {
// 如果已经选择了 k 个数
if (x == k) {
// 如果当前和是素数,则计数
if (prime(s)) {
sum++; // 累加符合条件的组合
}
return; // 返回,不再继续选择更多数
}
// 遍历从 h 到 n 位置的整数,选择未被选择过的数
for (int i = h; i <= n; i++) {
if (f[i] == 0) { // 如果第 i 个数没有被选择过
f[i] = 1; // 标记该数为已选择
s += a[i]; // 将该数加入当前组合的和中
dfs(x + 1, i + 1); // 递归选择下一个数,并将当前位置 i+1 作为下次的起始位置
s -= a[i]; // 回溯,撤销选择,恢复当前和
f[i] = 0; // 标记该数为未选择
}
}
}
int main() {
cin >> n >> k; // 输入 n 和 k
// 输入 n 个整数
for (int i = 1; i <= n; i++) {
cin >> a[i]; // 读入整数并存入数组 a
}
// 从第一个位置开始,进行深度优先搜索
dfs(0, 1);
// 输出符合条件的素数和的组合数
cout << sum;
}