已知 n n n 个整数 x 1 , x 2 , ⋯ , x n x_1,x_2,\cdots,x_n x1,x2,⋯,xn,以及 1 1 1 个整数 k k k( k < n k
3 + 7 + 12 = 22 3+7+12=22 3+7+12=22
3 + 7 + 19 = 29 3+7+19=29 3+7+19=29
7 + 12 + 19 = 38 7+12+19=38 7+12+19=38
3 + 12 + 19 = 34 3+12+19=34 3+12+19=34
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数: 3 + 7 + 19 = 29 3+7+19=29 3+7+19=29。
第一行两个空格隔开的整数 n , k n,k n,k( 1 ≤ n ≤ 20 1 \le n \le 20 1≤n≤20, k < n k
第二行 n n n 个整数,分别为 x 1 , x 2 , ⋯ , x n x_1,x_2,\cdots,x_n x1,x2,⋯,xn( 1 ≤ x i ≤ 5 × 1 0 6 1 \le x_i \le 5\times 10^6 1≤xi≤5×106)。
输出一个整数,表示种类数。
4 3
3 7 12 19
1
【题目来源】
NOIP 2002 普及组第二题
这道题又是真题不过感觉和上次讲的扫雷游戏差距还是比较大(难道后来题目简单了?)这道题要使用DFS算法来解,再加上素数的判断,才可以解出来。n是否是素数判断方法:
int sushu(int b){
int i;
if(b<2)
return 0;
for(i=2;i*i<=b;i++)
if(b%i==0)
return 0;
return 1;
}
DFS传送门
DFS是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。属于盲目搜索,最糟糕的情况算法时间复杂度为O(!n)。
#include
int n,k,a[25],t;
int sushu(int b){
int i;
if(b<2)
return 0;
for(i=2;i*i<=b;i++)
if(b%i==0)
return 0;
return 1;
}
void dfs(int num,int sum,int j){
int i;
if(num==k){
if(sushu(sum))
t++;
return;
}
for(i=j;i<n;i++)
dfs(num+1,sum+a[i],i+1);
return;
}
int main(){
int i;
scanf("%d %d",&n,&k);
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
dfs(0,0,0);
printf("%d",t);
return 0;
}
难度相较于之前有一些提升,需要使用DFS算法和判断素数才可以解出来这道题。