题目描述
已知 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 (1<=n<=20,k<n)
x1,x2,…,xn (1<=xi<=5000000)
输出格式:
屏幕输出,格式为:
一个整数(满足条件的种数)。
输入输出样例
本题用dfs方法。
#include<stdio.h>
#include<iostream>
#include<map>
#include<vector>
#include<math.h>
using namespace std;
map <int,int> maps;
int Nums[20];
bool book[20] = { false }; //记录数字是否被用过
int n; //一共n个数
int ans; //最终答案
int IsPrime(int n) //判素数
{
for (int i = 2; i <= sqrt(1.0*n); ++i)
if (n%i == 0)
return 0;
return 1;
}
int j;
void dfs(int k,int last,int num)
{
//last目的是从之前的下一个数开始遍历,为的是去除重复的等式(数字相同,但位置不同)
//num是k个数的和
if (!k) //当有k个数相加完后就退出递归
{
if (IsPrime(num)) //判素数
{
ans++; //是素数就ans++
}
return;
}
for (int i = last; i < n; i++)
{
if (!book[i]) //如果这个数没用过
{
num += Nums[i]; //加上一个数字的值
book[i] = true; //这个数字标记为已用
dfs(k - 1, i+1, num);//从这个数字之后开始寻找下一个数字
book[i] = false;//这个数字搜索完后标记为可用
num -= Nums[i]; //同时num减去这个数字的值
}
}
}
int main()
{
//freopen("1.txt", "r", stdin);
cin >> n;
int k;
cin >> k;
for (int i = 0; i < n; i++)
cin >> Nums[i];
dfs(k, 0, 0);
cout << ans;
return 0;
}