用回溯法求从1~n中取k个不同数的不同组合,然后求以这些组合为下标的k个数之和,判断其是否为素数。可以利用测试法判断某个数是否为素数。
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define N 22
int n, k, x[N], y[N], used[N], ans = 0;
void get_i(int &x) {
char ch = getchar();
x = 0;
while(!isdigit(ch)) ch = getchar();
while(isdigit(ch)) {
x = x * 10 + ch - '0';
ch = getchar();
}
}
// 快速幂
int qmod(int a, int x1, int x) {
long long tmp;
if(x1==1)
return a;
else if(x1==0)
return 1;
tmp = qmod(a, x1>>1, x);
if(x1&1)
return ((tmp * a) % x * tmp) % x;
return (tmp * tmp) % x;
}
// 测试法判定x是否为素数
int isPrime(int x) {
int a, t = 4;
srand(time(NULL));
while(t--) {
a = rand() % (x - 1) + 1;
if(qmod(a, x-1, x)!=1)
return 0;
}
return 1;
}
int judge() {
int i, tmp = 0;
for(i=1; i<=k; i++)
tmp += x[y[i]];
return isPrime(tmp);
}
void dfs(int m) {
int i;
if(m==k+1) { // 得到一个组合
ans += judge();
return;
}
for(i=y[m-1]; i<=n; i++) {
if(!used[i]) {
y[m] = i;
used[i] = 1;
dfs(m+1);
used[i] = 0;
}
}
}
int main() {
ios::sync_with_stdio(false);
int i;
get_i(n), get_i(k);
for(i=1; i<=n; i++)
get_i(x[i]);
y[0] = 1;
dfs(1);
cout<