这道题属于运用递归方法解决组合型枚举问题。具体而言,我们需要在完成组合型枚举的基础上,对每一种选取的组合进行求和操作,接着判断这些和是否为素数,最后输出满足和为素数这一条件的组合数量。其实,在解决该问题时,我们可以在基础的组合型枚举模板代码之上,添加一个用于判断某数是否为素数的函数,就能实现需求。
【代码示例】
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N=25;
int n,k;
int arr[N];
int q[N];
int res = 0;
//判断一个数是否是素数
bool isPrime(int num){
if(num <= 1) return false;
if(num == 2) return true;
if(num%2 == 0) return false;
for(int i=3;i<=sqrt(num);i+=2){
if(num%i == 0){
return false;
}
}
return true;
}
// 深度优先搜索函数,x 表示当前已经选了多少个数,start 表示从哪个数开始选
void dfs(int x,int start){
if(x == k){
int add = 0;
for(int i=0;i<k;i++){//循环计算取数之后的和
add += arr[i];
}
if(isPrime(add)){
res ++;
}
return;
}
for(int i=start;i<n;i++){
arr[x] = q[i];
dfs(x+1,i+1);
arr[x] = 0;
}
}
int main(){
cin>>n>>k;
for(int i=0;i<n;i++){
cin>>q[i];
}
dfs(0,0);
cout << res <<endl;
return 0;
}
易错分析——索引问题
1. 数组索引问题
在
dfs
函数的递归终止条件中,你使用for(int i = 0; i <= k; i++)
来计算所选数的和,这会导致数组越界。因为arr
数组中实际存储了k
个元素,有效索引范围是从0
到k - 1
,所以循环条件应该是for(int i = 0; i < k; i++)
。2. 输入数组索引问题
在
main
函数中,你将输入的数存储在q
数组中,索引从0
开始。但在dfs
函数里,你使用arr[x] = q[i];
来赋值,而i
是从start
开始的,这里会出现索引不匹配的问题。应该将q
数组的索引调整为i - 1
。3.
dfs
函数的start
参数问题在
main
函数中调用dfs(0, 1);
,这里start
从1
开始,而数组索引是从0
开始的,会导致逻辑错误。应该将start
初始化为0
。