题目描述
已知 n 个整数 x1,x2,⋯,xn,以及 1 个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为:
3+7+12=22
3+7+19=29
77+12+19=38
3+12+19=34
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:3+7+19=29。
输入格式
第一行两个空格隔开的整数 n,k(1≤n≤20,k<n)。
第二行 n 个整数,分别为 x1,x2,⋯,xn(1≤xi≤5e6)。
输出格式
输出一个整数,表示种类数。
输入输出样例
输入 #1复制
4 3 3 7 12 19输出 #1复制
1说明/提示
【题目来源】
NOIP 2002 普及组第二题
代码:
1.
#include <bits/stdc++.h>
using namespace std;
int n,k,sn[1000010],sum[1000010],ans[1000010],cnt=1,da;
void dfs(int x,int l){//x代表数字的编号,l代表第几个数字
ans[l]=sn[x];//存数字
if(l==k){//选了k个后
for(int i =1;i<=k;i++) sum[cnt]+=ans[i];//求和
cnt++;
}else{
for(int i=x+1;i<=n;i++){//不重复选 相当于选组合
dfs(i,l+1);
}
}
}
bool ss(int x){//素数判定
if(x<2) return 0;
else{
for(int i = 2;i*i<x;i++){
if(x%i==0) return 0;
}
}
return 1;
}
int main(){
cin >> n >>k;
for(int i =1;i<=n;i++){
cin >> sn[i];
}
sort(sn+1,sn+n);//可以不排,依旧AC
for(int i = 1;i<=n;i++){
dfs(i,1);//从第一个数字搜
}
for(int i = 1;i<=cnt-1;i++){
if(ss(sum[i])) da++;//如果是素数答案+1
}
cout << da;
return 0;
}
2.
#include <bits/stdc++.h>
using namespace std;
int n,k;
int s[1000010],sum;
int ans[1000010],cnt;
bool ss(int x){
if(x<2) return 0;
for(int i = 2;i*i<x;i++){
if(x%i==0) return 0;
}
return 1;
}
void dfs(int now,int d){
ans[d]=s[now];
if(d==k){
sum=0;
for(int i = 1;i<=k;i++){
sum+=ans[i];
}
if(ss(sum)) cnt++;
return;
}
for(int i = now+1;i<=n;i++){
dfs(i,d+1);
}
}
int main(){
cin >> n >> k;
for(int i = 1;i<=n;i++){
cin >> s[i];
}
for(int i = 1;i<=n;i++){
dfs(i,1);
}
cout << cnt;
return 0;
}