首页 > 代码库 > CODEVS 1008选数

CODEVS 1008选数

题目描述 Description

已知 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)。

输入描述 Input Description

 键盘输入,格式为:
  n , k (1<=n<=20,k<n)
  x1,x2,…,xn (1<=xi<=5000000)

输出描述 Output Description

屏幕输出,格式为:
  一个整数(满足条件的种数)。

样例输入 Sample Input

4 3
3 7 12 19

样例输出 Sample Output

1

数据范围及提示 Data Size & Hint

(1<=n<=20,k<n)
(1<=xi<=5000000)

 
思路:这类似于求n个数中选k个数的组合问题。
将选出的k个数相加判断是否是素数,如果是ans++。
这道题还有一个坑点是所给出的数全都是1,所以这里需要加一个特判
代码:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 using namespace std;
 5 int n,k,ans;
 6 int num[30],sum[30];
 7 bool vis[30];
 8 bool same()
 9 {
10     int x=num[1];
11     for(int i=2;i<=n;i++)
12         if(x!=num[i])return 0;
13     return 1;
14 }
15 bool prime(int x)
16 {
17     if(x==2)return 1;
18     for(int i=2;i<=sqrt(x);i++)
19         if(x%i==0)return 0;
20     return 1;
21 }
22 void dfs(int x)
23 {
24     if(x>k)
25     {
26         int cnt=0;
27         for(int i=1;i<=k;i++)
28             cnt+=sum[i];
29         if(prime(cnt))ans++;
30     }
31     else
32     for(int i=1;i<=n;i++)
33         if(num[i]>sum[x-1] && !vis[i])
34         {
35             sum[x]=num[i];
36             vis[i]=1;
37             dfs(x+1);
38             vis[i]=0;
39         }
40 }
41 int main()
42 {
43     cin>>n>>k;
44     for(int i=1;i<=n;i++)
45         cin>>num[i];
46     dfs(1);
47     if(same() && prime(num[num[1]*k]))
48     {
49         int a=1,b=1;
50         for(int i=n-k+1;i<=n;i++)
51             a*=i;
52         for(int i=1;i<=k;i++)
53             b*=i;
54         cout<<a/b;
55         return 0;
56     }
57     cout<<ans;
58     return 0;
59 }

 

CODEVS 1008选数