(bfs)lintcode中等1892 · 扫雷

题目

描述
现在有一个简易版的扫雷游戏。你将得到一个n*m大小的二维数组作为游戏地图。
每个位置上有一个值(0或1,1代表此处没有雷,0表示有雷)。
你将获得一个起点的位置坐标(x,y),x表示所在行数,y表示所在列数(x,y均从0开始计数)。
若当下位置上没有雷,则上下左右四个方向均可以到达,若当下位置有雷,则不能再往新的方向移动。
返回所有可以到达的坐标。

数据范围

0 答案返回一个任意顺序的数组,数组包括所有可以到达的位置坐标。

样例

样例1
输入:
[[1,0,0,0],[1,0,0,0],[0,1,1,1],[0,1,0,0]]
[0,1]
输出:
[[0,1]]
解释:
[0,1]位置上是0,不能再往新的地方走,只能到达这一个位置

样例2
输入:
[[1,0,0,0],[1,0,0,0],[0,1,1,1],[0,1,0,0]]
[1,0]
输出:
[[0,0],[1,0],[1,1],[2,0],[0,1]]
解释:
[1,0]位置上是1,所以可以走到[[0,0],[1,1],[2,0]],其中只有[0,0]位置上是1可以继续走到[0,1],然后不能再走了。

分析

解读题意,给一个二维数组代表地图,一个一维数组代表当前位置,二维数组中,0代表地雷,1代表空地,任何一个格子都可以走到,但是如果当前位置是地雷,就不能再走,要求返回一个二维的数组,数组中的每个元素代表可以到达的地方

一道基础的bfs题,直接广搜四个方向,并且在走过的地方设置标记不再走

代码部分

1.初始化

递归需要的参数
1.地图
2.初始的x和y
3.地图的边界
4.当前格子的状态(时候走过)
5.存放当前的格子x和y的二维数组(答案)

   	int x=Start[0];
    	int y=Start[1];
    	int rowlen=Mine_map.size();
    	int collen=Mine_map[0].size();
    	vector<vector<int> > vis(rowlen,
		vector<int>(collen));
		vector<vector<int> > ans;

初始化状态数组都为0代表都没走过

		for(int i=0;i<rowlen;i++)		//初始化所有状态 
			for(int j=0;j<collen;j++)
			{
				vis[i][j]=0;
			}
2.bfs

深度优先搜索和广度优先搜索,思路相同,都是先判断现在要做的事情,然后判断出口条件

当前要做的事情
分别判断四个方向,判断下一个位置是否超出边界,判断下一个位置是否走过,判断当前位置是否有地雷
如果都符合,就走到下一步

		//现在要做的事情	右左下上 
		if(x+1<maxx&&vis[x+1][y]==0&&_map[x][y]==1)		
			bfs(_map,x+1,y,maxx,maxy,ans,vis);
		if(x-1>=0&&vis[x-1][y]==0&&_map[x][y]==1)
			bfs(_map,x-1,y,maxx,maxy,ans,vis);
		if(y+1<maxy&&vis[x][y+1]==0&&_map[x][y]==1)
			bfs(_map,x,y+1,maxx,maxy,ans,vis);
		if(y-1>=0&&vis[x][y-1]==0&&_map[x][y]==1)
			bfs(_map,x,y-1,maxx,maxy,ans,vis); 

出口
出口条件是什么,什么时候需要返回,当超出边界,或者能走的格子全部走完,就返回,仔细一看,这些都包括在了我们设置的条件中,所以我们只需要将当前所在的格子放入答案中,然后标记当前的格子为走过的状态

		//出口
		vector<int> nowpos;	
		nowpos.push_back(x);
		nowpos.push_back(y);
		ans.push_back(nowpos);	//记录当前位置 
		
		vis[x][y]=1; 		//标记当前位置已走过

完整代码

class Solution {
public:
	void bfs(vector<vector<int>> &_map,int x,int y,
	int &maxx,int &maxy,vector<vector<int> > &ans,vector<vector<int> > &vis)
	{
		//出口
		vector<int> nowpos;	
		nowpos.push_back(x);
		nowpos.push_back(y);
		ans.push_back(nowpos);	//记录当前位置 
		
		vis[x][y]=1; 		//标记当前位置已走过

		//现在要做的事情	右左下上 
		if(x+1<maxx&&vis[x+1][y]==0&&_map[x][y]==1)		
			bfs(_map,x+1,y,maxx,maxy,ans,vis);
		if(x-1>=0&&vis[x-1][y]==0&&_map[x][y]==1)
			bfs(_map,x-1,y,maxx,maxy,ans,vis);
		if(y+1<maxy&&vis[x][y+1]==0&&_map[x][y]==1)
			bfs(_map,x,y+1,maxx,maxy,ans,vis);
		if(y-1>=0&&vis[x][y-1]==0&&_map[x][y]==1)
			bfs(_map,x,y-1,maxx,maxy,ans,vis); 
	}

    vector<vector<int>> Mine_sweeping(vector<vector<int>> &Mine_map,
	 vector<int> &Start) {
    	int x=Start[0];
    	int y=Start[1];
    	int rowlen=Mine_map.size();
    	int collen=Mine_map[0].size();
    	vector<vector<int> > vis(rowlen,
		vector<int>(collen));
		vector<vector<int> > ans;
        		
		for(int i=0;i<rowlen;i++)		//初始化所有状态 
			for(int j=0;j<collen;j++)
			{
				vis[i][j]=0;
			}
		

		
		bfs(Mine_map,x,y,rowlen,collen,ans,vis);
		
		return ans;
    }
};

总结

bfs和dfs唯一的区别就是,dfs是沿着一条路径走到不能再走,bfs是所有能走的路都走,思考的方向都是一样的,都是先判断能做的事情,在判断出口条件

你可能感兴趣的:(算法,广度优先)