4th day

BFS和DFS专题(今天的老哥讲的老仔细了,之前看这个都看不懂做了题目之后感觉确实有点入门的感觉)

 

贴一个大佬的整理:https://www.cnblogs.com/aiguona/p/7268667.html

下面是来自大佬博客的深搜广搜的模板

三、模板

 

  1.深搜

复制代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
char map[1000][1000];//用来存储图的信息

/*标记是否搜索过,本题目没有使用,因为是一次访问,直接将访问过的修改即可*/
int logo[1000][1000];

int m,n,sum;

/*表示八个方向,四个方向时,将后面四组删掉就可以了*/
int dir[8][2]= {0,1, 0,-1, 1,0, -1,0, 1,1, 1,-1, -1,1, -1,-1};

void DFS(int x,int y)
{
    if(x>=0&&y>=0&&x<n&&y<m)//这里是判断是否越界,根据题目要求改写
    {
        if(map[x][y]=='W')//如果符合条件就继续递归。
        {
            map[x][y]='.';//标记为‘.’防止多次访问
            for(int i=0; i<8; i++)//因为八个方向,所以循环八次。
                DFS(x+dir[i][0],y+dir[i][1]);
        }
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        sum=0;
        memset(logo,0,sizeof(map));
        getchar();
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
            {
                cin>>map[i][j];
            }
            getchar();
        }
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
                if(map[i][j]=='W')
                {
                    DFS(i,j);
                    sum++;//计数
                }
        }
        cout<<sum<<endl;
    }
}
复制代码

 

  2.广搜

复制代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#define MAX 0x3f3f3f3f
using namespace std;
int map[305][305];//存节点信息
int vis[305][305];//标记数组
int dir[4][2]= {-1,0, 1,0, 0,1, 0,-1};//上下左右四个方向
int end;
struct node
{
    int x,y;//两点表示节点位置
    int time;
} start;//入队列使用
queue<node> q;//队列,自己维护用来存储节点信息
int bfs(int x,int y)
{
    memset(vis,0,sizeof(vis));
    start.x=x,start.y=y,start.time=0;//将传递过来的0.0节点放入结构体
    vis[x][y]=1;//标记为已搜过
    q.push(start);//入队列
    while(!q.empty())
    {
        node now=q.front();//取队头元素
        q.pop();
        if(map[now.x][now.y]==MAX)
        {
            return now.time;//如果符合条件,返回;根据题意自己写符合的条件。
        }
        for(int i=0; i<4; i++)//四个方向入队列
        {
            start.x=now.x+dir[i][0],start.y=now.y+dir[i][1];//将第一个方向的入队列
            start.time=now.time+1;
            if(start.x>=0&&start.y>=0&&vis[start.x][start.y]==0&&start.time<map[start.x][start.y])//判断是否越界
            {
                vis[start.x][start.y]=1;
                q.push(start);
            }
        }
    }
    return -1;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(map,MAX,sizeof(map));
        for(int j=0; j<n; j++)
        {
            int x,y,time;
            scanf("%d%d%d",&x,&y,&time);
            if(map[x][y]>time)
                map[x][y]=time;
            for(int i=0; i<4; i++)//自己建图过程,一般不需要自己建图
            {
                int cx,cy;
                cx=x+dir[i][0],cy=y+dir[i][1];
                if(cx>=0&&cy>=0)
                    if(map[cx][cy]>time)
                        map[cx][cy]=time;
            }
        }
        int ans=bfs(0,0);//从00点开始广搜,根据题目要求具体定
        cout<<ans<<endl;
    }

}

根据今天的题目,深搜广搜各有自己不同的用法,广搜在找最短路径上面很有用处,但是相对来说空间复杂度较高//

B - Dungeon Master(hdu)

这道题目是一道三维的广搜,是bfs的典型模板题,这里其实为将来处理多维的提供了一个结构体的思路(之前学长使用pair去连接两个数,而用struct也可以,总之只要把他们连起来就可以了)

注意点主要是在输入问题还有临界的判断条件上,这是两个易错点

贴一下自己写的代码

#include <iostream>

#include <algorithm>

#include <cstdio>

#include <string.h>

#include <queue>

using namespace std;

typedef struct

{

    int a,b,c;

}node;

const int inf=0x3f3f3f3f;

char mp[35][35][35];//存储地图

int tx[10]={0,1,-1,0,0,0,0};

int ty[10]={0,0,0,1,-1,0,0};

int tz[10]={0,0,0,0,0,1,-1};//人物移动的方向

int dis[35][35][35];//到出口的距离,类比时间

int px,py,pz,fx,fy,fz;

int l,r,c;

void bfs()

{

    node pos;

    pos.a=px,pos.b=py,pos.c=pz;

    queue<node>q;

    q.push(pos);

    dis[px][py][pz]=0;

    while(!q.empty())

    {

       int x=q.front().a,y=q.front().b,z=q.front().c;

       q.pop();

       for(int i=1;i<=6;i++)

       {

           int xx=x+tx[i],yy=y+ty[i],zz=z+tz[i];

           if(xx>=0&&xx<=l-1&&yy>=0&&yy<=r-1&&zz>=0&&zz<=c-1&&dis[xx][yy][zz]==inf&&mp[xx][yy][zz]!='#')

           {

              dis[xx][yy][zz]=dis[x][y][z]+1;

              node pu;

              pu.a=xx,pu.b=yy,pu.c=zz;

              q.push(pu);

           }

       }

    }

}

int main()

{

    char hc;

    while(scanf("%d %d %d",&l,&r,&c)!=EOF)

    {

       memset(dis,inf,sizeof(dis));

       if(l==0&&r==0&&c==0)

       {

           break;

       }

       for(int i=0;i<l;i++)

       {

           for(int j=0;j<r;j++)

           {

              scanf("%s",mp[i][j]);

              //printf("%s\n",mp[i][j]);

              for(int k=0;k<c;k++)

              {

                  if(mp[i][j][k]=='S')

                  {

                     px=i;

                     py=j;

                     pz=k;

                  }

                  if(mp[i][j][k]=='E')

                  {

                     fx=i;

                     fy=j;

                     fz=k;

                  }

              }

           }

       } //找初始位置

       bfs();

       int ans=dis[fx][fy][fz];

       //printf("%d\n",dis[fx-1][fy][fz]);

       if(ans==inf)

       {

           printf("Trapped!\n");

       }

       else

       {

           printf("Escaped in %d minute(s).\n",ans);

       }

    }

    return 0;

}

这个其实我觉得特别有代表,在bfs的水题当中

 

dfs现在目前还是只做了n皇后那题,思路就是遍历判断每一个位置行不行,最后存储下来,但是dfs还缺少一定的理解(明天需要好好看看,摸点内容追上那帮大佬)

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stdlib.h>
#include <iostream>
#include <string.h>
int sum=0;
int a[11]={0}; 
int flag=1;
int t,i;
void dfs(int n)
{
	if(n==t+1)
	{
		sum++;
		return ;
	}
		for(int i=1;i<=t;i++)
		{
			flag=1;
			a[n]=i;//第n个皇后所在的列数
			for(int j=1;j<n;j++)
			{
				if(a[j]==i||(abs(j-n)==abs(a[j]-i)))//判断是否同列、主对角线,副对角线 
				{
					flag=0;
					break;
				}
			}
			if(flag==1)
			{
				//a[i]=0;
				dfs(n+1);
			}
		}
}
int main()
{
	int u;
	int ans[20]={0};
	for(i=1;i<=10;i++)
	{
		memset(a,0,sizeof a);
		sum=0;
		t=i;
		dfs(1);
		ans[i]=sum;
	}
	while(scanf("%d",&u)!=EOF)
	{
		if(u==0)
		{
			break;
		}
	    printf("%d\n",ans[u]);
	}
	return 0;
}

 

 n皇后的代码
 
主要点是在回溯以及回溯之后的初始化
 
 
还是要更加努力!!
posted @ 2021-01-23 20:04  Treasure-  阅读(84)  评论(0)    收藏  举报