P1036 选数
题目描述
https://www.luogu.com.cn/problem/P1036
从nn个整数中任选kk个整数相加,可分别得到一系列的和。例如当n=4,k=3 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=293+7+19=29。
思路说明
这条题目是一条求组合的题目,组合在计算机上面,一般用递归处理,以n=5, k=2为例,假设数据为 1 2 3 4 5。
先选第一个数字:
第一个数字选择1,然后再 2 3 4 5里面再进行求组合的计算,这很显然是一个递归过程,递归的出口是k=1
第一个数字选择2,然后再在3 4 5里面再进行求组合的计算,显然又是一个递归过程,递归的出口仍然是k=1
...
依次的,直到每个数字都选完
代码
#include <iostream>
#include <cmath>
using namespace std;
int is_prime(int n)
{
int i;
int s = sqrt(n);
if(n == 1)
return 0;
for(i=2; i<=s; i++) {
if(n % i == 0) {
break;
}
}
return i > s;
}
void _get(int *array, int *visit, int l, int n, int k, int *sum)
{
if(k == 1) {
int tmp = 0;
visit[l] = 1;
for(int i=0; i<n; i++) {
if(visit[i]) {
tmp += array[i];
}
}
if(is_prime(tmp)) {
*sum += 1;
}
visit[l] = 0;
return;
}
visit[l] = 1;
for(int i=l+1; i<n; i++) {
_get(array, visit, i, n, k-1, sum);
}
visit[l] = 0;
}
int get(int *array, int n, int k)
{
int *visit = new int[n]();
int sum = 0;
for(int i=0; i<n; i++)
{
_get(array, visit, i, n, k, &sum);
}
delete [] visit;
return sum;
}
int main(int argc, char **argv)
{
int n,k;
int *array;
while(cin >> n >> k) {
array = new int [n];
for(int i=0; i<n; i++) {
cin >> array[i];
}
cout << get(array, n, k) << endl;
delete [] array;
}
return 0;
}
浙公网安备 33010602011771号