首页 > 其他分享 >搜索

搜索

时间:2024-09-16 16:24:43浏览次数:1  
标签:case tx temp ty int break 搜索

1、BFS 广度优先搜索

一般用于地图的搜索遍历,最短路中的SPFA也是

洛谷 P1126 机器人搬重物

<1> 对于面对方向的计算 设四个方向分别为 0, 1, 2, 3 转向的时候只需要 (原方向代号 + 4 ± 1)% 4 就可以得到转向后面对的新方向

<2>对于每种状态,构建hash,在每次走后判断该种情况是否已经出现,如果没有出现,标记为出现,反之,不继续搜索

代码:

#include<bits/stdc++.h>
using namespace std;
const int my[4] = {0, 1, 0, -1}, mx[4] = {-1, 0, 1, 0};
int n, m, maze[60][60];
bool vis[20000];
inline int fun(int a, int b, int c){return c * 2700 + a * 51 + b;};//计算对应的数值
struct pos{
	int x, y;
	int f;
	int mov;
};
queue<pos> que;
inline bool zq(int x, int y){//计算会不会与障碍物相撞
	if(maze[x][y] || maze[x + 1][y] || maze[x][y + 1] || maze[x + 1][y + 1]){
		return true;
	}
	return false;
}
inline void bfs(){
	int x, y, tx, ty, f, d, mov, lx, ly;
	char c;
	cin >> x >> y >> tx >> ty >> c;
	switch(c){
		case 'N' : f = 0;
		break;
		case 'E' : f = 1;
		break;
		case 'S' : f = 2;
		break;
		case 'W' : f = 3;
		break;
	}
	pos temp;//初始化机器人的起点
	temp.x = x, temp.y = y, temp.f = f, temp.mov = 0;
	que.push(temp);
	while(!que.empty()){
		temp = que.front();
		que.pop();
		x = temp.x, y = temp.y, f = temp.f, d = fun(x, y, f), mov = temp.mov;
		if(x == tx && y == ty){//如果到达终点,直接输出并返回
			cout << mov ;
			return;
		}
		if(vis[d]) continue;//如果该种情况已经出现过了,则不进行搜索
		vis[d] = 1;//将该种情况标记为已经出现
		temp.mov++;//步数++
		temp.f = (f + 4 - 1) % 4; que.push(temp);//左转 并放入队列中
		temp.f = (f + 4 + 1) % 4; que.push(temp);//右转 并放入队列中
		temp.f = f;//重置方向
		for(int i = 1; i <= 3; ++i){//走路
			lx = x + mx[f] * i, ly = y + my[f] * i;//计算走到的地点
			if(lx <= 0 || ly <= 0 || lx >= n || ly >= m || zq(lx, ly)) break;//如果出界,就没必要再走了
			temp.x = lx, temp.y = ly; que.push(temp);//将走到的状况放入队列中
		}	
	}
	cout << -1 << endl;//无法走到终点,输出-1
}
int main(){
	cin >> n >> m;
	for(int i = 1; i <= n; ++i){
		for(int j = 1; j <= m; ++j){
			cin >> maze[i][j];
		}
	}
	bfs();
	return 0;
}

<1>先找到出发点,将其放到q队列中,(q队列储存当前步骤能进行走的点)然后将出发点改成正常道路

<2>将q队列中的点取出,按照给定方向进行走,将得到的点放入t队列中

<3>将t队列的点放到q队列中,作为下一次操作的起始点

<4>最终得到的q队列就是结果

代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 55;
char mapp[N][N];
int r, c, w;
string ss;
bool vis[N][N];
int dx[7] = {0, -1, 0, 1, 0}, dy[7] = {0, 0, 1, 0, -1};
queue<pair<int, int>> q, t;

// 坐标和方向 
inline void dfs(int x, int y, int p){
	int tx = x + dx[p];
	int ty = y + dy[p];
	if(mapp[tx][ty] == 'X' || tx > r || tx < 1 || ty > c || ty < 1) return;
	if(vis[tx][ty] == true) return;
	vis[tx][ty] = true;
	t.push(make_pair(tx, ty));
	dfs(tx, ty, p);
}

inline void bfs(string dir){
	int fx;
	switch(dir[0]){
		case 'N' : fx = 1;
		break;
		case 'S' : fx = 3;
		break;
		case 'W' : fx = 4;
		break;
		case 'E' : fx = 2;
	}
	while(!q.empty()){
		int tx = q.front().first;
		int ty = q.front().second;
		q.pop();
		dfs(tx, ty, fx);
	}
	memset(vis, false, sizeof vis);
	while(!t.empty()){
		q.push(t.front());
		t.pop();
	}
}

int main(){
	cin >> r >> c;
	for(int i = 1; i <= r; ++i){
		for(int j = 1; j <= c; ++j){
			cin >> mapp[i][j];
			if(mapp[i][j] == '*'){
				q.push(make_pair(i, j));
				mapp[i][j] = '.';
			}
		}
	}
	cin >> w;
	for(int i = 1; i <= w; ++i){
		cin >> ss;
		bfs(ss);
	}
	while(!q.empty()){
		int tx = q.front().first;
		int ty = q.front().second;
		q.pop();
		mapp[tx][ty] = '*';
	}
	for(int i = 1; i <= r; ++i){
		for(int j = 1; j <= c; ++j){
			cout << mapp[i][j];
		}
		cout << endl;
	}
	return 0;
}

标签:case,tx,temp,ty,int,break,搜索
From: https://www.cnblogs.com/lyx9785/p/18416402

相关文章

  • Day15 二叉树part05| LeetCode 654.最大二叉树,617.合并二叉树 ,700.二叉搜索树中的搜索
    654.最大二叉树654.最大二叉树classSolution{publicTreeNodeconstructMaximumBinaryTree(int[]nums){if(nums.length==1)//遍历到了叶子节点{returnnewTreeNode(nums[0]);}intmaxValue=nums[0......
  • 力扣热题100 - 二叉树:二叉搜索树中第 K 小的元素
    题目描述:题号:230给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 小的元素(从1开始计数)。解题思路:思路一:中序遍历二叉树+ 计数根据二叉搜索树的性质,中序遍历得到的节点的顺序是从小到大递增的。所以可以一边中序遍历,一边计数......
  • PanSoo盘搜,百度网盘、阿里云盘、夸克网盘、迅雷网盘UC网盘资源搜索神器-2024年好用的
    ......
  • 代码随想录算法训练营,9月16日 | 235. 二叉搜索树的最近公共祖先,701.二叉搜索树中的插
    235.二叉搜索树的最近公共祖先题目链接:235.二叉搜索树的最近公共祖先文档讲解︰代码随想录(programmercarl.com)视频讲解︰二叉搜索树的最近公共祖先日期:2024-09-16想法:相比于普通二叉树,二叉搜索树从上往下遍历,在qp中间的值的一定是公共祖先,而第一个则是最近,因为此时你在这个祖......
  • 禁忌搜索算法(TS算法)求解实例---旅行商问题 (TSP)
    目录一、采用TS求解TSP二、旅行商问题2.1实际例子:求解6个城市的TSP2.2==**求解该问题的代码**==2.3代码运行过程截屏2.4代码运行结果截屏(后续和其他算法进行对比)三、==如何修改代码?==3.1减少城市坐标,如下:3.2增加城市坐标,如下:四、禁忌搜索算法(TabuSearc......
  • 力扣热题100 - 二叉树:验证二叉搜索树
    题目描述:题号:98给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。有效 二叉搜索树定义如下:节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。解题思路:思路一......
  • 一张图精通多种搜索算法的选择策略(经验篇)
    在探索数据的海洋中,搜索算法是指引我们找到目标的灯塔。从简单的线性搜索到高效的二分搜索,再到深度优先与广度优先的图搜索,每种算法都以其独特的方式优化着搜索过程。无论是在数组、树结构还是散列表中,正确的搜索算法能显著提升查找效率。本文将带你一探线性搜索、二分搜索、深度优......
  • 【洛谷 P1596】[USACO10OCT] Lake Counting S 题解(深度优先搜索)
    [USACO10OCT]LakeCountingS题面翻译由于近期的降雨,雨水汇集在农民约翰的田地不同的地方。我们用一个的网格图表示。每个网格中有水(W)或是旱地(.)。一个网格与其周围的八个网格相连,而一组相连的网格视为一个水坑。约翰想弄清楚他的田地已经形成了多少水坑。给出约翰田地的示意图,......
  • 代码随想录 -- 二叉树 -- 二叉搜索树中的众数
    501.二叉搜索树中的众数-力扣(LeetCode)思路:定义一个字典1,key 为二叉树的值,value 为二叉树的值出现的次数。定义一个字典2,key 为二叉树的值出现的次数,value (列表)为二叉树的值。找出字典2中最大的key,返回其 value 即可。 classSolution(object):defcreate......
  • 实战13-搜索模块滑动效果01
    import{getHomeDataApi}from'../api/home';import{BannerListDataSource,INavList,IPlanList,ITitleList}from'../api/models/HomeData';importSwiperLayoutfrom'../views/Home/SwiperLayout';import{window}from'......