算法1-3 选数

题目描述

已知 n 个整数 x1​,x2​,⋯,xn​,以及 1 个整数 k(k

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​≤5×10^{6})。

输出格式

输出一个整数,表示种类数。

输入输出样例

输入 #1

4 3
3 7 12 19

输出 #1

1
#include
#include
using namespace std;

int n, k;
int a[22], ans;

//判断质数 
bool prime(int num)
{
	if(num<2) return 0;
	if(num==2) return 1;
	for(int i=2; i<=sqrt(num); ++i)
	{
		if(num%i == 0) return 0;
	}
	return 1;
}

//从n个数中找k个数的问题 →从 flag 到n个数中找 num 个数的问题 
void f(int flag, int num, int sum)  //sum:和 
{
	if(num==0)  //已经找齐了,判断是否为质数 
	{
		if(prime(sum)) ans++; 
		return;
	}
	
	if(n-flag+1 < num) return; //剩余的数不够找num个数 
	
	for(int i=flag; i<=n; ++i)
	{
		f(i+1, num-1, sum+a[i]);
	}
	return;
}

int main()
{
	cin>>n>>k;
	for(int i=1; i<=n; ++i)
	{
		cin>>a[i];
	}
	
	f(1, k, 0);
	
	cout<

具体执行过程示例

假设 n = 4k = 3a = {3, 7, 12, 19}

  1. 初始调用 f(1, 3, 0)

    • for 循环从 i = 1 开始,选择 a[1] = 3,调用 f(2, 2, 3)

      • 在 f(2, 2, 3) 中,for 循环从 i = 2 开始,选择 a[2] = 7,调用 f(3, 1, 10)

        • 在 f(3, 1, 10) 中,for 循环从 i = 3 开始,选择 a[3] = 12,调用 f(4, 0, 22)

          • 在 f(4, 0, 22) 中,num == 0,判断 sum = 22 是否为质数,不是质数,使用 return 结束该分支。

        • 继续 for 循环,选择 a[4] = 19,调用 f(5, 0, 29)

          • 在 f(5, 0, 29) 中,num == 0,判断 sum = 29 是否为质数,是质数,ans 加 1,使用 return 结束该分支。

      • 继续 for 循环,选择 a[3] = 12,调用 f(4, 1, 15)

        • 在 f(4, 1, 15) 中,for 循环从 i = 4 开始,选择 a[4] = 19,调用 f(5, 0, 34)

          • 在 f(5, 0, 34) 中,num == 0,判断 sum = 34 是否为质数,不是质数,使用 return 结束该分支。

      • 继续 for 循环,选择 a[4] = 19,调用 f(5, 1, 22)

        • 在 f(5, 1, 22) 中,n - flag + 1 < num,直接使用 return 结束该分支。

    • 继续 for 循环,选择 a[2] = 7,调用 f(3, 2, 7)

      • 类似地,递归调用并返回。

    • 继续 for 循环,选择 a[3] = 12,调用 f(4, 2, 12)

      • 类似地,递归调用并返回。

    • 继续 for 循环,选择 a[4] = 19,调用 f(5, 2, 19)

      • 在 f(5, 2, 19) 中,n - flag + 1 < num,直接使用 return 结束该分支。

你可能感兴趣的:(搜索,递归)