蓝桥杯之搜索专题,腾讯T3大牛手把手教你

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注运维)
img

正文

#include <bits/stdc++.h>
#define int long long
#define f first
#define s second
#define all(x) x.begin(),x.end()
using namespace std;
using pii = pair<int,int>;

int n;
pii a,b; // A/B
char g[105][105]; // 存图
int st[105][105];
int ans = 1e9;
int dx[] = {0,0,0,-1,1};
int dy[] = {0,1,-1,0,0};
// 当前点,步数,以及上一个点的状态
void dfs(int x, int y, int cnt, char status) {
	if (x == b.f && y == b.s) { // 合法答案
		ans = min(ans, cnt);
		return ;
	}

	for (int i = 1;i <= 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		if (nx<=0||nx>n||ny<=0||ny>n||st[nx][ny]) continue;
		if (g[x][y]!='A' && status == g[nx][ny]) continue;
		st[nx][ny] = 1;
		dfs(nx,ny,cnt+1,g[nx][ny]);
		st[nx][ny] = 0;
	}
}
void solve() {
    cin >> n;
    for (int i = 1;i <= n; i++) {
    	for (int j = 1;j <= n; j++) {
    		cin >> g[i][j];
    		if (g[i][j] == 'A') a = {i,j};
    		if (g[i][j] == 'B') b = {i,j};
    	}
    }
    dfs(a.f, a.s, 0, 1);
    ans = (ans == 1e9?-1:ans);
    cout << ans;
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t = 1;
    while (t--) {
        solve();
    }
    return 0;
}

T5: 飞机降落(23年蓝桥杯省赛)

解题思路:

DFS飞机降落的顺序

剪枝策略:当有飞机无法降落时回溯

代码:
// DFS
#include <bits/stdc++.h>
#define int long long
#define f first
#define s second
#define all(x) x.begin(),x.end()
using namespace std;

const int N = 1e5 + 50;
struct node {
	int t; // 最早降落时间
	int d; // 周旋时间
	int l; // 降落花费的时间
}a[20];
int n;
string ans;
bool st[N]; // 标记当前飞机是否降落
// 已经降落了几架飞机以及上一架飞机降落的时间
void dfs(int u,int last) {
	if (u >= n) { // 飞机全部安全降落,递归退出点
        ans = "YES";
        return ;
    } 
    for (int i = 1;i <= n; i++) {
        if (st[i]) continue;
        // 1.判断当前飞机是否可以降落
        if (a[i].t + a[i].d < last) return ; // 不能降落,回溯
        // 2.思考u+1个位置由谁降落
        st[i] = true;
        dfs(u + 1,max(a[i].t,last) + a[i].l);
        st[i] = false;
    }
}
void solve() {
    cin >> n; // 飞机架数
    for (int i = 1;i <= n; i++) st[i] = false; // 初始化st数组
    for (int i = 1;i <= n; i++) {
    	cin >> a[i].t >> a[i].d >> a[i].l;
    }
    ans = "NO";
    dfs(0,0);
    cout << ans << '\n';
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t; cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

T6:卡片换位(16年蓝桥杯省赛)

解题思路:DFS

交换可以看成移动空格,手动模拟一下就会发现,最多17就一定能实现交换,我们枚举交换的次数0~17,然后对于每一个答案做dfs,能满足条件的第一个答案即为最小值;

但是DFS不是正解,正解是BFS

代码
// DFS遍历
#include <bits/stdc++.h>
#define int long long
#define f first
#define s second
#define all(x) x.begin(),x.end()
using namespace std;
using pii = pair<int,int>;

const int N = 5;
char g[N][N];
pii a,b,k;
int sum = 0;
int num = -1;
int dx[] = {0,0,0,-1,1};
int dy[] = {0,1,-1,0,0};
void dfs(int x,int y,int cnt) {
	if (g[a.f][a.s] == 'B' && g[b.f][b.s] == 'A') { // 目标状态
		num = cnt;
		return ;
	}
	if (cnt > sum) return ;
	for (int i = 1;i <= 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		if (nx<0||nx>=2||ny<0||ny>=3) continue;
		swap(g[x][y], g[nx][ny]); // 交换
		dfs(nx, ny, cnt+1);
		swap(g[x][y], g[nx][ny]); // 回溯
	}

}
void solve() {
    for (int i = 0;i < 2; i++) {
        string s1; getline(cin, s1);
        for (int j = 0;j < 3; j++) g[i][j] = s1[j];
    }
    for (int i = 0;i < 2; i++) {
    	for (int j = 0;j < 3; j++) {
    		if (g[i][j] == 'A') a = {i,j}; // A的位置
    		if (g[i][j] == 'B') b = {i,j}; // B的位置
    		if (g[i][j] == ' ') k = {i,j}; // 空格的位置
     	}
    }

    for (int i = 1;i <= 20; i++) { // 枚举次数
    	sum = i;
    	dfs(k.f,k.s,0);
    	if (num != -1) {
    		cout << num;
    		return ;
    	}
    }
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t = 1;
    while (t--) {
        solve();
    }
    return 0;
}

BFS

写了好多BFS的题,最重要的一点就是判重,写的好几个题都是通过二维转一维,即将图转化成字符串来保存状态,使用map/set来标记判重

T1:青蛙跳杯子

解题思路

我们用BFS遍历青蛙跳杯子的所有状态,定义map<string,int> 来标记每个状态,去掉重复的状态,当到达目标状态时的步数即为答案;

注意:每次遍历都有一个找空杯子的过程,我们可以用string的find函数来快速找到空杯子的位置;

代码
// BFS搜索,map去重,注意状态要还原
#include <bits/stdc++.h>
#define int long long
#define f first
#define s second
#define all(x) x.begin(),x.end()
using namespace std;

const int N = 1e5 + 50;
string s,e;
int n;
unordered_map<string, int> ump;
int dx[] = {0,-3,-2,-1,1,2,3};// 向左右跳的6种情况
queue<string> q;
void bfs() {
	// 初始化
	q.push(s);
	ump[s] = 0;
	while (q.size()) {
		string now = q.front(); q.pop(); // 当前串
		int cnt = ump[now]; // 当前次数
		if (now == e) { // 合法答案
			cout << cnt;
			return ;
		}
		int k = now.find('*'); // 空杯子的位置
		for (int i = 1;i <= 6; i++) { // 枚举6个位置
			int nk = k + dx[i];
			if (nk < 0 || nk >= n) continue;
			swap(now[nk], now[k]); // 移动
			if (!ump[now]) {
				ump[now] = cnt + 1;
				q.push(now); // 当前是一个新状态
			}
			swap(now[nk], now[k]); // 还原
		}
	}
}
void solve() {
    cin >> s;
    cin >> e;
    n = s.size();
    bfs();
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t = 1;
    while (t--) {
        solve();
    }
    return 0;
}

T2:卡片换位(16年蓝桥杯省赛)

解题思路:BFS

该题可以说是上一题的二维版本,但是我们任然使用一维字符串来存状态,就需要一维和二维的转换;

  • 二维转一维:直接将每一行拼接即可
  • 一维转二维:除法和取模

BFS搜索空格的交换方案,并用字符串记录当前方案的状态,遇到的第一个合法答案就是最小步数(因为BFS有最短路性质),map即标记了当前状态,又保存当前状态与步数之间的关系;

注意:

  1. 使用unordered_map比map效率更高
  2. 注意要使用getline读入带空格的字符串
代码
#include <bits/stdc++.h>
#define int long long
#define f first
#define s second
#define all(x) x.begin(),x.end()
using namespace std;

int dx[] = {0,0,0,-1,1};
int dy[] = {0,1,-1,0,0};
unordered_map<string, int> ump; // 存状态与步数的关系
queue<string> q;
string s;
int a,b; // 存A/B的下标
void bfs() {
	q.push(s);
    ump[s] = 0;

    while (q.size()) {
    	auto now = q.front(); q.pop(); // 当前状态
    	int cnt = ump[now]; // 当前步数
    	if ((int)now.find('A')==b && (int)now.find('B')==a) { // 交换成功
    		cout << cnt;
    		return ;
    	}
    	int pos = now.find(" "); // 找空格的位置
    	int x = pos/3, y = pos%3; // 转二维
    	
    	for (int i = 1;i <= 4; i++) {
    		int nx = x + dx[i];
    		int ny = y + dy[i];
    		if (nx<0||nx>=2||ny<0||ny>=3) continue;
    		swap(now[pos], now[nx*3+ny]); // 交换
    		if (!ump[now]) { // 当前是新状态
    			ump[now] = cnt + 1; // 标记
    			q.push(now);
    		}
    	    swap(now[pos], now[nx*3+ny]); // 还原
    	}
    }
} 
void solve() {
    for (int i = 1;i <= 2; i++) {
    	string t;
    	getline(cin, t); // 带空格的字符串的读入方式
    	s += t;
    }
    a = s.find('A');
    b = s.find('B');
    bfs();
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t = 1;
    while (t--) {
        solve();
    }
    return 0;
}

T3:九宫重排(13年蓝桥杯国赛)

解题思路

该题是卡片换位的升级版,由2*3变成了3*3,思路几乎一摸一样,不做讲解

代码
#include <bits/stdc++.h>
#define int long long
#define f first
#define s second
#define all(x) x.begin(),x.end()
using namespace std;

const int N = 1e5 + 50;
string s,e;
unordered_map<string, int> ump;
queue<string> q;
int dx[] = {0,0,0,-1,1};
int dy[] = {0,1,-1,0,0};

int bfs(string s, int cnt) {
	// 初始化
	q.push(s);
	ump[s] = cnt;
	while (q.size()) {
		string now = q.front(); q.pop(); // 当前状态
		int cnt = ump[now]; // 当前步数

		if (now == e) { // 目标状态
			return cnt;
		}

		int pos = now.find('.'); // 空格的位置
		int x = pos/3, y = pos%3; // 一维转二维
		for (int i = 1;i <= 4; i++) {
			int nx = x + dx[i];
			int ny = y + dy[i];
			if (nx < 0 || nx >= 3 || ny < 0 || ny >= 3) continue;
			swap(now[pos], now[nx*3 + ny]); // 交换
			if (!ump[now]) { // 为处理过的状态
				ump[now] = cnt + 1;
				q.push(now);
			}
            swap(now[pos], now[nx*3 + ny]); // 交换 // 还原
		}
	}
	return -1;
}

void solve() {
    cin >> s >> e;
    int ans = bfs(s,0); // 当前字符串和次数
![](https://img-blog.csdnimg.cn/img_convert/9a8cb5f8c0ec69e6499adead0da6e95b.png)



最全的Linux教程,Linux从入门到精通

======================

1.  **linux从入门到精通(第2版)**

2.  **Linux系统移植**

3.  **Linux驱动开发入门与实战**

4.  **LINUX 系统移植 第2版**

5.  **Linux开源网络全栈详解 从DPDK到OpenFlow**



![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/59742364bb1338737fe2d315a9e2ec54.png)



第一份《Linux从入门到精通》466页

====================

内容简介

====

本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。



![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/9d4aefb6a92edea27b825e59aa1f2c54.png)



**本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。**

> 需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论




**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注运维)**
![img](https://img-blog.csdnimg.cn/img_convert/efcb3d765e3e503fb99e1e0113d13a84.jpeg)

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
供读者免费下载。



![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/9d4aefb6a92edea27b825e59aa1f2c54.png)



**本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。**

> 需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论




**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注运维)**
[外链图片转存中...(img-wE1h1ECv-1713279312422)]

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值