洛谷题解 P1036 选数

原题传送门

0.前言 这个题在咕了很久以后又做了一遍,也是卡了好几次,wtcl
1.算法 DFS(深度优先搜索)
2.思路
这道题拿到题之后会非常明显地发现是一道DFS的题,而且运用递归是这道题的核心,也是DFS的核心。

我们可以把这道题分为两个步骤

  • 搜索
  • 判断素数

搜索就是一个简单的板子类的代码,判断素数用埃拉托斯特尼(Eratosthenes)筛法埃氏筛就可以完成(别的貌似也不想写)

3.Code

#include<iostream>
#include<cstdio>
using namespace std;
inline void read(int &x){      //快读
	int f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	x*=f;
}
int n,k;
int x[21];
int cnt;
inline bool judge(int m){      //埃氏筛判断素数
	for(int i=2;i*i<=m;i++){
		if(m%i==0) return false;
	}
	return true;
}
inline void search(int now,int choose,int sum){
        //now指当前遍历到第几个数
        //choose指当前选了几个数
        //sum也很好理解,就是当前选的所有数之和
	if(choose==k){      //边界条件,当当前选择的数的个数与指定个数相同时
		if(judge(sum)==1) cnt++;      //若是素数,计数器++并结束
		return;
	}
	if(now==n+1) return;      //如果遍历的数大于总数,则溢出结束
	search(now+1,choose+1,sum+x[now]);      //对于一个数,要么选,要么不选。这一行为选的情况,下一行为不选的情况
	search(now+1,choose,sum);
}
int main(){
	read(n);read(k);
	for(int i=1;i<=n;i++) read(x[i]);
	search(1,0,0);      //开始从第一个数遍历,一个数也没选,总和为0
	printf("%d",cnt);
	return 0;
}
本文欢迎转载,转载时请注明本文链接
原文地址:https://www.cnblogs.com/-pwl/p/13640207.html