标签:sum 广搜 数组 end 自定义 循环 入队 迷宫 状态
DFS(深度优先搜索)
从起点出发,朝任一个可能的方向走,走过的点要做标记,一直向前走。若走不了了,就回退一步,从这一个状态走向没有走过的另一个方向。
之所以称为深度优先搜索,因为它是朝着一个方向一直走到底,以深度优先,然后回溯。
DFS一般用的是递归的方法。
迷宫问题
给一个迷宫,0表示道路,1表示墙壁,找出一条从左上角到右下角的最短路径
首先建立一个next[4][2]数组,表示下一步要走的方向,自定义方向的优先级,本题是从左上到右下,
那么,我可以按照下,右,上,左的顺序,则next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
遍历四个方向的代码为
for(int i=0;i<4;i++) tx=x+next[i][0];ty=y+next[i][1];//x,y为当前位置坐标,tx,ty为下一步要走的坐标
或者建立两个一维数组
int nx[4]={0,1,0,-1},ny={1,0,-1,0};
for(int i=0;i<4;i++)
{
int tx=x+nx[i],ty=y+ny[i];
}
还需要建立一个bool类型的vis[maxn][maxn]数组,来判断是否已经走过这条路
int nx[4]={0,1,0,-1},ny={1,0,-1,0}; void judge(int x,int y)//判断是否越界和是否已经走过 { return x>=0&&y>=0&&x<=n&&y<=m&&v[x][y]==0;//n为行数,m为列数 } void dfs(int x,int y,int step) { if(x==end1&&y==end2)//到达终点 { ans=min(ans,step); return; } v[x][y]=1;//标记为走过 for(int i=0;i<4;i++) { int tx=x+nx[i],ty=y+ny[i]; if(judge(tx,ty)) { dfs(tx,ty,step+1);//更新步数 } } v[x][y]=0;//回退时,清除标记, }
给出n个正整数a1,a2....an,和一个正整数k,问是否能从这n个数中选取若干个,使其和为k
int ans=0,a[N],b[N],sum=0,step=0;//ans表示有几种情况,step代表每种情况需要几个数使其和为k void dfs(int i,int sum,int step) { if(i==n+1)//当i等于n时,因为又递归了一次,所以要判断是否等于n+1,注意只有在n个数全部都枚举完了再判断sum是否等于k { if(sum==k) { ans++; b[ans]=step; } return; } dfs(i+1,sum+a[i],step+1);//加上a[i]的情况,数量加1 dfs(i+1,sum,step);//不加a[i]的情况 }
因为DFS采用递归的方法,所以很费时间,如果不剪枝的话,是很难AC的;
最简单的剪枝是sum>k时,直接返回
struct node { int x,y,dis; node(int a,int b,int c):x(a),y(b),dis(c){} }start; int bfs(node start) { bool v[siz][siz]={0}; queue<node>q; q.push(start); v[start.x][start.y]=1; while(!q.empty()) { node now=q.front(); q.pop(); if(now.x==endx&&now.y=endy) return now.dis; for(int i=0;i<4;i++) { int tx=now.x+dx[i],ty=now.y+dy[i]; if(can-move(tx,ty)) { v[tx][ty]=1; node newnode(tx,ty,dis+1); q.push(newnode); } } } return -1; }
标签:sum 广搜 数组 end 自定义 循环 入队 迷宫 状态
原文地址:https://www.cnblogs.com/175426-hzau-zxjc-con/p/9382291.html