原题传送门
0.前言 这个题在咕了很久以后又做了一遍,也是卡了好几次,wtcl
1.算法 DFS(深度优先搜索)
2.思路
这道题拿到题之后会非常明显地发现是一道DFS的题,而且运用递归是这道题的核心,也是DFS的核心。
我们可以把这道题分为两个步骤
- 搜索
- 判断素数
搜索就是一个简单的板子类的代码,判断素数用埃拉托斯特尼(Eratosthenes)筛法埃氏筛就可以完成(别的貌似也不想写)
3.Code
#include<iostream>
#include<cstdio>
using namespace std;
inline void read(int &x){ //快读
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
int n,k;
int x[21];
int cnt;
inline bool judge(int m){ //埃氏筛判断素数
for(int i=2;i*i<=m;i++){
if(m%i==0) return false;
}
return true;
}
inline void search(int now,int choose,int sum){
//now指当前遍历到第几个数
//choose指当前选了几个数
//sum也很好理解,就是当前选的所有数之和
if(choose==k){ //边界条件,当当前选择的数的个数与指定个数相同时
if(judge(sum)==1) cnt++; //若是素数,计数器++并结束
return;
}
if(now==n+1) return; //如果遍历的数大于总数,则溢出结束
search(now+1,choose+1,sum+x[now]); //对于一个数,要么选,要么不选。这一行为选的情况,下一行为不选的情况
search(now+1,choose,sum);
}
int main(){
read(n);read(k);
for(int i=1;i<=n;i++) read(x[i]);
search(1,0,0); //开始从第一个数遍历,一个数也没选,总和为0
printf("%d",cnt);
return 0;
}