目录
题目:
给定一个包含 n
个整数的数组 a
,需要从这 n
个整数里挑选出 k
个数,计算它们的和。接着判断这些和是否为质数,统计和为质数的组合数量。
代码解析:
#include<bits/stdc++.h>
int n,k,cnt = 0;
int a[21];
// 判断一个数是否为质数的函数
int prime(int x){
for(int i = 2;i <= sqrt(x);i++) {
if(x%i == 0) return 0;
}
return 1;
}
// 深度优先搜索函数,用于生成所有可能的 k 个数的组合
void dfs(int x,int sum,int num){
// 当已经选取了 k 个数时
if(num == k+1){
// 判断这些数的和是否为质数,如果是则计数器加 1
if(prime(sum)) cnt++;
return;
}
// 从 x 开始遍历,尝试选取不同的数
for(int i = x;i <= n-k+num;i++){
// 递归调用,选取下一个数,更新和与选取的数的数量
dfs(i+1,sum+a[i],num+1);
}
}
int main(){
// 输入 n 和 k 的值
scanf("%d %d",&n,&k);
// 输入数组 a 的元素
for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
// 从第一个数开始进行深度优先搜索
dfs(1,0,1);
// 输出和为质数的组合数量
printf("%d",cnt);
return 0;
}
代码详细解释
-
全局变量:
-
n
:表示数组中元素的数量。
-
k
:表示要选取的元素个数。
-
cnt
:用于统计和为质数的组合数量,初始值为 0。
-
a[21]
:存储输入的整数数组。
-
prime
函数:
-
该函数用于判断一个数 x
是否为质数。
-
通过遍历从 2 到 x 的所有数,检查 x
是否能被其中任何一个数整除。若能,则 x
不是质数,返回 0;否则返回 1。
-
dfs
函数:
-
参数:
-
x
:当前可以选取的数的起始位置。
-
sum
:当前已选取的数的和。
-
num
:当前已选取的数的数量。
-
终止条件:当 num
等于 k + 1
时,表示已经选取了 k
个数,此时调用 prime
函数判断 sum
是否为质数,若是则 cnt
加 1。
-
递归过程:通过 for
循环从 x
开始遍历到 n - k + num
,每次选取一个数加入到 sum
中,并递归调用 dfs
函数,更新 x
为 i + 1
,sum
为 sum + a[i]
,num
为 num + 1
。
-
main
函数:
-
读取 n
和 k
的值。
-
读取数组 a
的元素。
-
调用 dfs
函数,从第一个数开始进行深度优先搜索。
-
输出 cnt
的值,即和为质数的组合数量。
复杂度分析
-
时间复杂度:由于需要生成所有可能的 Cnk 种组合,每种组合判断质数的时间复杂度为 O(m)(m 为组合的和),所以总的时间复杂度为 O(Cnk×m)。
-
空间复杂度:主要是递归调用栈的空间,递归深度最大为 k
,所以空间复杂度为 O(k)。