周六900C++2022-10-15 深搜

 

深度优先搜索

深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法。它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,这种尽量往深处走的概念即是深度优先的概念。 属于盲目搜索,最糟糕的情况算法时间复杂度为O(!n)。

 

 

 

 

 

 深搜的模板:

void dfs(int x,int y)
{
    if(搜索要满足的条件){相应的操作;return; }
    for(循环搜索的方向,即探寻下一步)
    {    根据当前的x,y得到下一步的坐标tx,ty
        if(对tx,ty做越界判断)continue;
        if(当前坐标vis[tx][ty]==0 && 下一步在地图上是可走的)
        {    vis[tx][ty] = 1;
            更新相应数据,如求和、步长等等
            dfs(tx,ty); 以tx,ty作为新的起点传入dfs中去寻找符合条件的下一步
            vis[tx][ty] = 0;
            将更新的数据回溯到未更新前,如步长-1,求和--等 
        }
    }
}

 

 

 

TZOJ 3286: Lake Counting

 

#include<bits/stdc++.h>
using namespace std;
char ma[1005][1005]; //地图 
int vis[1005][1005]; //标记数组,标记某点坐标是否已访问过 
int nex[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},{1,1},{1,-1},{-1,-1}}; //方向数组,表面搜索下一步的方向,这里为右下左上 
int n,m;
void dfs(int x,int y)
{
    for(int i=0;i<8;i++)
    {
        int tx = x+nex[i][0]; //下一步坐标tx = 当前坐标x+第i个方向的第0个数nex[i][0]
        int ty = y+nex[i][1];
        if(tx<1||tx>n||ty<1||ty>m)continue; //越界判断
        if(ma[tx][ty]=='W' && vis[tx][ty]==0)//如果第(tx,ty)个点是湖泊W,且在vis上没访问过
        {
            vis[tx][ty] = 1; //访问 
            dfs(tx,ty); //继续搜索 
        } 
    }
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        cin>>ma[i][j];
        
            
    //以上是输入
    int ans = 0; //湖泊数
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(ma[i][j]=='W' && vis[i][j]==0) //如果第(i,j)个点是湖泊W,且在vis上没访问过
            {
                vis[i][j] = 1; //访问
                ans++; //湖泊数+1
                dfs(i,j);//将i,j相邻的所有湖泊搜索标记 
            } 
        } 
    cout<<ans;
     return 0;
}

 

 

 

TZOJ 4833: 选数

#include<bits/stdc++.h>
using namespace std;
int ma[105]; //地图 
int vis[105]; //标记数组,标记某点坐标是否已访问过 
int n,k,sum,ans,len;
void dfs(int x);
int prime(int n);
int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>ma[i];
    //以上是输入
    dfs(1); //从0开始 
    cout<<ans;
     return 0;
}
void dfs(int x)
{
    if(len==k){
        if(prime(sum))ans++;
        return;
    }
    for(int i=x;i<=n;i++)
    {
        if(vis[i]==0)
        {
            sum+=ma[i];
            len++;
            vis[i] = 1;
            dfs(i+1);
            len--;
            vis[i] = 0;
            sum-=ma[i];
        }
    }
}
int prime(int n)
{
    if(n==1)return 0;
    for(int i=2;i*i<=n;i++)
        if(n%i==0)return 0;
    return 1;
}

 

posted @ 2022-10-15 13:32  CRt0729  阅读(51)  评论(0编辑  收藏  举报