上一期介绍了广度优先搜索,这一期介绍另一种搜索算法,深度优先搜索。
按照它们俩的理念来说,广度优先就是尽可能的多做尝试,比如要你在迷宫中找到目标点,我们就需要看遍四周的路看看那个可以走通,能走通就加入备选队列中,然后不断从队列中取坐标点继续重复上述操作直到找到目标或者无路可走,按照广度优先搜索的特性,它适合用来求最短路问题,或者是求某个操作的最小值。
深度优先搜索呢,使用它的主要目的就是“一条路走到黑”,比如在上一段描述的迷宫问题中,深度优先搜索就是找到一个可以走的格子就直接去到那个格子,然后继续看有哪个格子可以走继续走,直到无路可走或者到达终点,此时返回上一个节点。总结一下,深度优先搜索像一个不撞南墙不回头的人,遇到能走的路就走,直到不能走在倒回去,按照这个特性,我们需要标记走过的路,不然当遇到不能走的路时程序就成为死循环了。依照这个特点,深度优先搜索适合求解那种要求多种方案的问题,因为我们会尽可能地将每一种方案都试一遍。
下面来看一道深度优先搜索的问题:
一看题目要求我们输出一共多少种方案,果断选择一手深度搜索,利用简单递归就可以实现题目
需要注意的是判断素数的时候计数器i枚举到i*i>=sum的时候就该停了,可以节省一部分运行时间
具体思路可以看下面代码及注释
已知 n 个整数 x1,x2,⋯ ,xn以及 1个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当 n=4,k=3,44 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为:
3+7+12=22
3+7+19=29
7+12+19=38
3+12+19=34
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:3+7+19=293+7+19=29。
#include<iostream>
#include<cstring>
using namespace std;
#define N 30
int nums[N],ans,n,k;
bool iss(int sum)//判断是否是素数
{
int i;
for(i=2;i*i<sum;i++)
{
if(sum%i==0)
break;
}
if(i*i<sum)
return false;
return true;
}
void dfs(int i,int cnt,int sum)//i表示此时是第几个数
//cnt记录一共加了几个数,sum表示总和
{
if(cnt==k)//加到k个数了,判断一手
{
if(iss(sum))
ans++;
return ;
}
for(int j=i;j<n;j++)//
{
dfs(j+1,cnt+1,sum+nums[j]);//每次从下标为i的数开始累计,避免重复
}
return ;
}
int main()
{
cin>>n>>k;
for(int i=0;i<n;i++)
{
cin>>nums[i];
}
dfs(0,0,0);
cout<<ans;
return 0;
}
标签:优先,19,int,素数,搜索,深度
From: https://blog.csdn.net/weixin_74141526/article/details/137024618