NOIP200202选数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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选数的主要内容,如果未能解决你的问题,请参考以下文章