P1036 选数
题目链接:https://www.luogu.com.cn/problem/P1036

题目大意:
从n个整数中选出k个相加,统计所有可能的和中有多少个是素数,输出和为素数的选法数(不同选法即使和相同也分别计数)。
这个题目的所有选法恰好可以组成一棵树,我们可以用DFS深度搜索每一种可能性
我们从每个位置放什么数出发深度搜索所有可能性;

第 1 个位置能放的下标上界是 n−k+1 = 2,所以 12、19 不会出现在第 1 个位置;
我们定义初始数组,构建后存数据的数组,和从当前位置开始遍历的变量分别为,arr:读入数组;ans:存当前组合;start:可选下标起点。dfs 从 (1, 1) 开始
dfs 核心代码

然后数组按 1~n 存储,从 dfs(1, 1) 开始搜索

最后结果为:

完整代码:
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N=20;
int arr[N];
int ans[N];
int dd=0;
int n,k;
bool isPrime(int n) {
if (n <= 1) return false; // 0、1 不是素数
if (n == 2) return true; // 2 是唯一的偶素数
if (n % 2 == 0) return false; // 排除其他偶数
// 只检查奇数因子,且只需检查到 sqrt(n)
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) return false;
}
return true;
}
void dfs(int x,int stare){
//x为遍历域的最小值
//stare 为当前遍历开始的位置
if(x>k){//当遍历的位置到第四个开始统计计算
int sum=0;
for(int i=1;i<=k;i++){
sum+=ans[i];
}
if(isPrime(sum)){//判断是否为素数
dd++;
}
return ;//回溯上个支路
}
for(int i=stare;i<=n;i++){//stare初始为1
ans[x]=arr[i];//当前x位置数值为arr[i];
dfs(x+1,i+1);//递归进入下一个支路
ans[x]=0;//状态恢复
}
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>arr[i];
}
dfs(1,1);
cout<<dd;
}

浙公网安备 33010602011771号