NOIP200202选数

 

试题描述
    已知 n 个整数 x1,x2,…,xn,以及一个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为:
    3+7+12=22  3+7+19=29  7+12+19=38  3+12+19=34。
  现在,要求你计算出和为素数共有多少种。
  例如上例,只有一种的和为素数:3+7+19=29)。
 
输入
第一行两个正整数n和k,由一个空格分隔,第二行有n个整数x1,x2,…,xn,两两之间由一个空格分隔。 
输出
一个整数(满足条件的种数)。
输入示例
4 3
3 7 12 19
输出示例
1
其他说明
数据范围:1<=xi<=5000000,1<=n<=20,k<n
 

本题的难点在于不知道k具体是多少,所以不能用循环,只能用深搜。而这个深搜的递归有点不好理解。

 1 #include <iostream>
 2 #include <cmath>
 3 using namespace std;
 4 int a[50];
 5 int ans=0;
 6 int n,k;
 7 bool prime(int a)  //判断素数 
 8 {
 9     for(int i=2;i<sqrt(a);i++)   //比a的一半还大的数不可能被a整除,所以不用考虑。 
10         if(a%i==0) return false;
11     return true;
12 }
13 int sum(int f,int cnt,int temp) //f是当前位置,cnt是当前有几个数,temp是当前这cnt个数的和。 
14 {
15     if(cnt==k)
16         if(prime(temp)) ans++;
17     for(int i=f;i<=n;i++) sum(i+1,cnt+1,temp+a[i]);  //本循环是理解的难点 
18 }
19 int main()
20 {
21     scanf("%d%d",&n,&k);
22     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
23     sum(1,0,0);  //因为 k不确定,所以要用dfs来求出所有组合 
24     printf("%d",ans);
25     //system("pause");
26     return 0;
27 }
NOIP200202选数

 

posted @ 2016-01-29 10:40  姚呵呵  阅读(419)  评论(0编辑  收藏  举报