P1036 [NOIP 2002 普及组] 选数
题目描述
已知 个整数 ,以及 个整数 ()。从 个整数中任选 个整数相加,可分别得到一系列的和。例如当 ,, 个整数分别为 时,可得全部的组合与它们的和为:
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:。
输入格式
第一行两个空格隔开的整数 (,)。
第二行 个整数,分别为 ()。
输出格式
输出一个整数,表示种类数。
输入输出样例 #1
输入 #1
4 3
3 7 12 19
输出 #1
1
说明/提示
这依旧是个递归的题 但我们可以发现当n相同 而k相近时 只要给到的x不一样那么这个数据之间就不会存在递推 那么我们应该怎么办呢 考虑到这个n最大只有20 我们不妨来试试暴力枚举 而这个枚举本身也是一种递推 我们让x1当排头然后x2再当排头就这样不断下去就可以模拟完所有情况了 所以代码如下
#include <stdio.h>
int arr[25];//把数组定义为全局变量 方便我们后面的调用
int n,num;同理
int count=0;//计数器
bool Isshu(int n){
if(n==1){return false;}
else if(n==2){return true;}
else if(n%2==0){return false;}
else {
for(int i=2;i*i<=n;i++){
if(n%i==0){return false;}
}
return true;
}
}//判断是不是素数
void ans(int begin,int k,int sum){
if(k==0){
if(Isshu(sum)){count++;}
return ;//当我们所需要的数量变成0后 我们就开始判断是不是素数了 就可以反会了
}
if(begin-n+1<k){return ;}//如果我们剩下的树都不足以拿出来凑满 那么可以直接退出了
for(int i=begin,i<n,i++){
ans(begin+1,k-1,sum+arr[i]);//用下一个函数来判断而不是当前函数来判断可以保证每次的sum都不会一直积累
}
}
int main(){
scanf("%d %d",&n,&num);
for(int i=0;i<n;i++){
scanf("%d",&arr[i]);
}
ans(0,num,0);
printf("%d",count);
return 0;
}