选数(NOIP2002) 学习总结

//[问题描述]
//    已知 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)
//[输出]:
//  屏幕输出,格式为:
//  一个整数(满足条件的种数)。
//[输入输出样例]:
//  输入:
//   4 3
//   3 7 12 19
//  输出:
//   1
//    看一下n的取值范围 n<=20 则最坏的情况从n中选k个数,也不算很坏,有点数学基础的就可以算出。
//要解决此题 先写个prime 函数来判断 和是否为素数。然后回溯枚举所有情况,看代码。
#include <iostream>
#include <cmath>
using namespace std;
const int maxn = 30;
int n,k,ans = 0,sum = 0,path[maxn]={0};//ans用来记录每一种的和,sum用来记录总种数
int a[maxn] = {0};//a用来存读入的数据
int pos=0;
int prime (int m) {  //判断素数
    for (int i = 2;i < sqrt(m) + 1; i++) {
        if (m % i == 0) return 0;
    }
    return 1;
}

int search (int cur) {
    for (int j = cur;j < n; j++) {
        ans += a[j];
        path[pos++]=a[j];
        if (pos == k) {sum += prime (ans);}
        else search (j+1);
        ans -= a[j];//回溯
        pos--;
    }
}

int main() {
    cin >> n >> k;
    for (int i = 0;i < n; i++) {
        cin >> a[i];
    }
    search(0);
    cout << sum << endl;
}

 

posted @ 2014-02-09 13:01  闪光阳  阅读(1270)  评论(0编辑  收藏  举报