1-24 每日总结

今天学了广度优先搜索(bfs)以及AC的题

什么是bfs?

        BFS(广度优先搜索)是一种图遍历算法,它从一个起始点开始,逐层扩展搜索范围,直到找到目标节点为止。这种算法通常用于解决“最短路径”问题,比如在迷宫中找到从起点到终点的最短路径

        首先,你会从起点开始,检查所有与它相邻的位置,也就是距离起点为1的位置, 然后,你会继续向外扩展,检查所有距离起点为2的位置,以此类推,直到找到出口
在BFS中,你可以使用队列来存储待搜索的节点。起始点首先加入队列中,然后不断从队列中取出节点,检查它是否是目标节点。如果不是,就将它的所有未被访问过的邻居加入队列中。这样,队列中的节点总是按照它们距离起点的距离排序,先加入队列的节点总是先被取出来搜索。

通过这种方式,BFS可以找到起点到目标节点的最短路径。在实际应用中,BFS还可以用于拓扑排序、连通性检测等问题的解决。

废话不多说上题目

题目链接:https://www.luogu.com.cn/problem/P1825

题解:很明显这是一道bfs并且还使用了队列,这道题注意的是他的这个传送装置,进了传送装置就要改变位置,首先创建结构体队列内部三个成员坐标x,y以及temp表示时间,将起点入列并用个二维数组标记点已经走过;向四个方向进行搜索即可;

AC代码:

#include <iostream>
#include <cstring>
#include <cmath>
#include <iomanip> 
#include <algorithm>
#include <cstdio>
#include <stack>
#include <queue>
using namespace std;

using ll = long long;
#define up(h, n) for (int i = h; i <= n; i++) 
#define down(h, n) for(int i = h; i >= n; i--)
#define wh(x) while(x--)
#define node struct node
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
constexpr int N = 200005;
constexpr int mod = 1e9 + 7;

node{
	int x;
    int y;
	int temp;//时间
};
const int next1[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };// 四个方向
bool book[N][N];
char s[N][N];
int n, m,sum;
queue<node>q;//创建队列
void top(int *x, int *y) {  //传送装置更换位置
	up(1, n) {
		for (int j = 1; j <= m; j++){
			if (s[i][j] == s[*x][*y] && (i != *x || j != *y)) {
				*x = i; *y = j;
				return;
			}
		}
	}
}
int bfs(int x, int y) {
	q.push({ x,y,0 });
	book[x][y] = true;
	while (q.size()) {
		node t = q.front();
		q.pop();
		if (s[t.x][t.y] == '=') {// 判断是否到达终点
			return t.temp;
		}
		if (s[t.x][t.y] >= 'A' && s[t.x][t.y] <= 'Z') top(&t.x, &t.y);//判断是否是传送装置
		up(0, 3) {  // 遍历四个方向
			int tx = t.x + next1[i][0];
			int ty = t.y + next1[i][1];
			if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && book[tx][ty] == false && s[tx][ty] != '#') {
				book[tx][ty] = true;
				q.push({ tx,ty,t.temp + 1 }); // 入列
			}
		}   
	}
}
int main()
{
	ios;
	cin.tie(0); cout.tie(0);
	cin >> n >> m;
	int x, y;
	up(1, n) {
		for (int j = 1; j <= m; j++) {
			cin >> s[i][j];
			if (s[i][j] == '@') {
				x = i; y = j;
		     }
		}
	}
	sum = bfs(x, y);
	cout << sum << '\n';
	return 0;
}

题目链接:八皇后

题解:这题的话首先要读懂意思就是每行每列每条对角线只有一个棋子,知道这个便定义四个数组分别用来计数和标记即可最后运用dfs搜索原理即可AC.

AC代码;

#include <iostream>
#include <string>
#include <cmath>
#include <iomanip> 
#include <algorithm>
#include <stack>


using namespace std;

using ll = long long;
#define up(h,n) for(int i=h;i<=n;i++)
#define down(h,n) for(int i=h;i>=n;i--)
#define wh(x) while(x--)
#define node struct node
#define ios ios::sync_with_stdio(false)
constexpr int N = 100005;
constexpr int mod = 1e9 + 7;
typedef int SElemType;

int n,sum=0;
int a[105], b[105], c[105], d[105]; //a存结果,b数组用来标记,c,d用来标记对角线
void dfs(int x)
{
	if (x > n) {
		sum++;
		if (sum <= 3) { // 前三组数据输出
			up(1, n) {
				cout << a[i] << ' ';
			}
			cout << '\n';
		}
	}
	up(1, n) {
		if (b[i] == 0 && c[x + i] == 0 && d[x - i + 13] == 0) {
			a[x] = i;
			b[i] = 1; c[x + i] = 1; d[x - i + 13] = 1;// +13是因为两个相减可能为负数,
			dfs(x + 1);                               // n最大是13所以直接就+13
			b[i] = 0; c[x + i] = 0; d[x - i + 13] = 0;// 回溯
		}
	}
}
int main()
{
	cin >> n;
	dfs(1);
	cout << sum << '\n';
	return 0;
}

题目链接:求先序排列

题解:这道题的话,是二叉树的遍历序列,知道后序和中序遍历的话,后序的最后一个节点是根结点,然后找到中序根结点的位置分成左子树和右子树,然后又对左子树和右子树进行同样的操作即可得出答案;

AC代码:

#include <iostream>
#include <cstring>
#include <cmath>
#include <iomanip> 
#include <algorithm>
#include <cstdio>
#include <stack>
#include <queue>
using namespace std;

using ll = long long;
#define up(h,n) for(int i=h;i<=n;i++)
#define down(h,n) for(int i=h;i>=n;i--)
#define wh(x) while(x--)
#define node struct node
#define ios ios::sync_with_stdio(false)
constexpr int N = 305;
constexpr int mod = 1e9 + 7;
typedef int SElemType;


string a;
string b;
void dfs(string s, string k) {
	if (s.size() > 0) {
		char ch = k[k.size() - 1];//找到后序的根结点
		cout << ch;
		int t = s.find(ch); // find用来查找位置
		dfs(s.substr(0, t), k.substr(0, t));// substr用来截取字符串
		dfs(s.substr(t + 1), k.substr(t, k.size()-t- 1));//递归左右两边子树
	}
	else return ;
}
int main()
{
	cin >> a;
	cin >> b;
	dfs(a, b);
	return 0;
}

题目链接

  • 13
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值