P1036 [NOIP2002 普及组] 选数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<bits/stdc++.h>
using namespace std;
const int N=30;
int n,r;
int g[N]; //存用户输入的数
int arr[N]; //存答案
int res=0; //存种类数
bool is_prime(int y){ //求素数
if(y<2){ //1不是素数
return false;
}
for(int i=2;i<=y/i;i++){
if(y%i==0){
return false;
}
}
return true;
}
//k表示当前枚举到了哪个位置,start表示从几开始枚举
void dfs(int k,int start){
if((k-1)+n-start+1<r){ //剪枝
return;
}
if(k>r){
int sum=0;
for(int i=1;i<=k;i++){
sum+=arr[i];
}
if(is_prime(sum)){ //如果是素数
res++; //种类数+1
}
return; //不再DFS了
}
for(int i=start;i<=n;i++){
arr[k]=g[i];
dfs(k+1,i+1); //继续向下,深度优先
arr[k]=0; //恢复现场
}
}
int main(){
scanf("%d %d",&n,&r);
for(int i=1;i<=n;i++){
cin>>g[i];
}
dfs(1,1);
cout<<res<<endl;
return 0;
}