算法·搜索

news2025/3/9 23:56:22

搜索问题

搜索问题本质也是暴力枚举,一般想到暴力也要想到利用回溯枚举

排序和组合问题

回溯问题

图论中的搜索问题

  • 与一般的搜索问题一致,只不过要多定义方向

DFS和BFS的分析

DFS

  • DFS适合搜索所有路径,时间复杂度为 O ( n m ) O(n^m) O(nm),效率非常低

  • 只适合10~20这个数量级的方法

BFS













P1219 [USACO1.5] 八皇后 Checker Challenge

题目描述

一个如下的 6 × 6 6 \times 6 6×6 的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。

上面的布局可以用序列 2   4   6   1   3   5 2\ 4\ 6\ 1\ 3\ 5 2 4 6 1 3 5 来描述,第 i i i 个数字表示在第 i i i 行的相应位置有一个棋子,如下:

行号 1   2   3   4   5   6 1\ 2\ 3\ 4\ 5\ 6 1 2 3 4 5 6

列号 2   4   6   1   3   5 2\ 4\ 6\ 1\ 3\ 5 2 4 6 1 3 5

这只是棋子放置的一个解。请编一个程序找出所有棋子放置的解。
并把它们以上面的序列方法输出,解按字典顺序排列。
请输出前 3 3 3 个解。最后一行是解的总个数。

输入格式

一行一个正整数 n n n,表示棋盘是 n × n n \times n n×n 大小的。

输出格式

前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。

输入输出样例 #1

输入 #1

6

输出 #1

2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4

说明/提示

【数据范围】
对于 100 % 100\% 100% 的数据, 6 ≤ n ≤ 13 6 \le n \le 13 6n13

题目翻译来自NOCOW。

USACO Training Section 1.5

#define MAX_SIZE 1000009
using ll = long long;
using namespace std;
int n,ans=0;
vector<vector<int>>graph(20,vector<int>(20,0));
vector<int>temp;
bool isvalid(int h,int w) {

	for (int i = 1; i <= n; i++) {
		if (graph[i][w]) {
			return false;
		}
	}

	//bottom
	int bottom_upper = min(n - h, n - w);//h=2,w=1
	int bottom_lower = min(h - 1, w - 1);
	for (int i = 1; i<= bottom_upper; i++) {
		if (graph[h + i][w + i]) {
			return false;
		}
	}
	for (int i = 1; i <= bottom_lower; i++) {
		if (graph[h - i][w - i]) {
			return false;
		}
	}

	//top
	int top_upper = min(h - 1, n - w);
	int top_lower = min(w - 1, n - h);
	for (int i = 1; i <= top_upper;i++) {
		if (graph[h - i][w + i]) {
			return false;
		}
	}
	for (int i = 1; i <= top_lower; i++) {
		if (graph[h + i][w - i]) {
			return false;
		}
	}

	return true;


}

void dfs(int depth) {
	if (depth > n) {
		if (ans < 3) {
			for (auto item : temp) {
				cout << item << " ";
			}
			cout << endl;
		}
		ans++;
		return;
	}
	for (int i = 1; i <= n; i++) {
		if (isvalid(depth, i)) {
			temp.push_back(i);
			graph[depth][i] = 1;
			
			dfs(depth + 1);

			graph[depth][i] = 0;
			temp.pop_back();
		}
	}
}
void solve() {

	cin >> n;
	dfs(1);
	cout << ans;
}
signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	solve();
}

P1443 马的遍历

题目描述

有一个 n × m n \times m n×m 的棋盘,在某个点 ( x , y ) (x, y) (x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。

输入格式

输入只有一行四个整数,分别为 n , m , x , y n, m, x, y n,m,x,y

输出格式

一个 n × m n \times m n×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 − 1 -1 1)。

输入输出样例 #1

输入 #1

3 3 1 1

输出 #1

0    3    2    
3    -1   1    
2    1    4

说明/提示

数据规模与约定

对于全部的测试点,保证 1 ≤ x ≤ n ≤ 400 1 \leq x \leq n \leq 400 1xn400 1 ≤ y ≤ m ≤ 400 1 \leq y \leq m \leq 400 1ym400

DFS

  • 优点:它会探索所有的路径
  • 缺点:效率比较低
  • 一般搜索使用BFS比较多
# include<bits/stdc++.h>
#define MAX_VALUE 1000009
using ll = long long;
using namespace std;

int n, m, x, y;

int dir[8][2] = { 2,1, 1,2, -1,2, -2,1, -1,-2, -2,-1, 1,-2,2,-1 };

vector<vector<bool>>visited(500, vector<bool>(500, 0));
vector<vector<int>>graph(500, vector<int>(500, MAX_VALUE));

void dfs(int x, int y,int dist) {
	//cout << "x==" << x << " y==" << y << endl;
	graph[x][y] = min(graph[x][y], dist);
	for (int i = 0; i < 8; i++) {
		int next_x = x + dir[i][0];
		int next_y = y + dir[i][1];

		if (next_x>=1 && next_x<=n && next_y>=1 && next_y<=m && !visited[next_x][next_y]) {
			visited[next_x][next_y] = true;
			dfs(next_x, next_y,dist+1);
			visited[next_x][next_y] = false;
		}	
	}

}
void solve() {
	cin >> n >> m >> x >> y;
	dfs(x,y,0);

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			if (graph[i][j] == MAX_VALUE) {
				cout << -1 << "   ";
			}
			else {
				cout << graph[i][j] << "    ";
			}
		}
		cout << endl;
	}
}
signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	solve();
}

BFS

  • BFS:搜索效率比较高
  • 缺点:没有探索全部路径
  • 如果需要探索全部路径,需要在point结构体数组中保留visited作为局部变量
# include<bits/stdc++.h>
#define MAX_VALUE 1000009
using ll = long long;
using namespace std;

int n, m, x, y;

int dir[8][2] = { 2,1, 1,2, -1,2, -2,1, -1,-2, -2,-1, 1,-2,2,-1 };
vector<vector<int>>graph(500, vector<int>(500, MAX_VALUE));
vector<vector<bool>>visited(500,vector<bool>(500,false));
typedef struct point {
	int x, y,dist;
	point(int a, int b,int c) :x(a), y(b),dist(c) {};
}point;
queue<point>q;
void bfs() {
	q.push(point(x, y,0));
	while (!q.empty()) {
		point cur = q.front();
		graph[cur.x][cur.y] = min(cur.dist, graph[cur.x][cur.y]);
		q.pop();

		for (int i = 0; i < 8; i++) {
			int next_x = cur.x + dir[i][0];
			int next_y = cur.y + dir[i][1];

			if (next_x >= 1 && next_x <= n && next_y >= 1 && next_y <= m
				&& !visited[next_x][next_y]) {
				point p(next_x, next_y,cur.dist+1);
				visited[next_x][next_y] = true;
				q.push(p);
			}
			
		}
	}
}
void solve() {
	cin >> n >> m >> x >> y;
	bfs();
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			if (graph[i][j] == MAX_VALUE) {
				cout << -1 << "   ";
			}
			else {
				cout << graph[i][j] << "    ";
			}
		}
		cout << endl;
	}
}
signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	solve();
}

P1135 奇怪的电梯

题目背景

感谢 @yummy 提供的一些数据。

题目描述

呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第 i i i 层楼( 1 ≤ i ≤ N 1 \le i \le N 1iN)上有一个数字 K i K_i Ki 0 ≤ K i ≤ N 0 \le K_i \le N 0KiN)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如: 3 , 3 , 1 , 2 , 5 3, 3, 1, 2, 5 3,3,1,2,5 代表了 K i K_i Ki K 1 = 3 K_1=3 K1=3 K 2 = 3 K_2=3 K2=3,……),从 1 1 1 楼开始。在 1 1 1 楼,按“上”可以到 4 4 4 楼,按“下”是不起作用的,因为没有 − 2 -2 2 楼。那么,从 A A A 楼到 B B B 楼至少要按几次按钮呢?

输入格式

共二行。

第一行为三个用空格隔开的正整数,表示 N , A , B N, A, B N,A,B 1 ≤ N ≤ 200 1 \le N \le 200 1N200 1 ≤ A , B ≤ N 1 \le A, B \le N 1A,BN)。

第二行为 N N N 个用空格隔开的非负整数,表示 K i K_i Ki

输出格式

一行,即最少按键次数,若无法到达,则输出 -1

输入输出样例 #1

输入 #1

5 1 5
3 3 1 2 5

输出 #1

3

说明/提示

对于 100 % 100 \% 100% 的数据, 1 ≤ N ≤ 200 1 \le N \le 200 1N200 1 ≤ A , B ≤ N 1 \le A, B \le N 1A,BN 0 ≤ K i ≤ N 0 \le K_i \le N 0KiN

本题共 16 16 16 个测试点,前 15 15 15 个每个测试点 6 6 6 分,最后一个测试点 10 10 10 分。

DFS

#include <bits/stdc++.h>
#define MAX_VALUE 1000009
using ll = long long;
using namespace std;
int n, a, b,ans=MAX_VALUE;
vector<int>v(209,0);
vector<bool>visited(209, false);
void dfs(int st,int step=0) {
	
	//cout << "st==" << st << endl;
	if (st == b) {
		ans = min(ans, step);
		return;
	}
	if (st + v[st] <= n && !visited[st+v[st]]) {
		visited[st + v[st]] = true;
		dfs(st + v[st], step + 1);
		visited[st + v[st]] = false;
	}

	if (st -v[st] >= 1  && !visited[st - v[st]]) {
		visited[st - v[st]] = true;
		dfs(st - v[st], step + 1);
		visited[st - v[st]] = false;
	}

}
void solve() {
	cin >> n >> a>>b;
	for (int i = 1; i <= n; i++) {
		cin >> v[i];
	}
	dfs(a);
	cout << (ans==MAX_VALUE?-1:ans);
}
signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	solve();
}

BFS

#include <bits/stdc++.h>
#define MAX_VALUE 1000009
using ll = long long;
using namespace std;
int n, a, b,ans=MAX_VALUE;
vector<int>v(209, 0);
vector<bool>visited(209, false);

typedef struct node {
	int fr, step;
	node(int x, int y) :fr(x), step(y) {};
}node;

queue<node>q;
void bfs(int st) {
	q.push(node(st, 0));
	while (!q.empty()) {
		node cur=q.front();
		q.pop();
		//终止条件
		if (cur.fr == b) {
			ans = min(ans, cur.step);
		}

		if (cur.fr + v[cur.fr] <= n && !visited[cur.fr + v[cur.fr]]) {
			q.push(node(cur.fr + v[cur.fr], cur.step + 1));
			visited[cur.fr + v[cur.fr]] = true;
		}
		if (cur.fr - v[cur.fr] >= 1 && !visited[cur.fr - v[cur.fr]]) {
			q.push(node(cur.fr - v[cur.fr], cur.step + 1));
			visited[cur.fr - v[cur.fr]] = true;
		}
	}

}
void solve() {
	cin >> n >> a>>b;
	for (int i = 1; i <= n; i++) {
		cin >> v[i];
	}
	bfs(a);
	cout << (ans==MAX_VALUE?-1:ans);
}
signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	solve();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2311122.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《水利水电安全员考试各题型对比分析及应对攻略》

《水利水电安全员考试各题型对比分析及应对攻略》 单选题&#xff1a; 特点&#xff1a;四个选项中只有一个正确答案&#xff0c;相对难度较小。主要考查对基础知识的掌握程度。 应对攻略&#xff1a;认真审题&#xff0c;看清题目要求。对于熟悉的知识点&#xff0c;直接选择…

鸿蒙HarmonyOS-Navagation基本用法

Navagation基本用法 Navigation组件是路由导航的根视图容器&#xff0c;一般作为Page页面的根容器使用&#xff0c;其内部默认包含了标题栏&#xff0c;内容栏和公工具栏&#xff0c;其中内容区默认首页显示导航内容&#xff08;Navigation的子组件&#xff09;或非首页显示&am…

【AI深度学习网络】卷积神经网络(CNN)入门指南:从生物启发的原理到现代架构演进

深度神经网络系列文章 【AI深度学习网络】卷积神经网络&#xff08;CNN&#xff09;入门指南&#xff1a;从生物启发的原理到现代架构演进【AI实践】基于TensorFlow/Keras的CNN&#xff08;卷积神经网络&#xff09;简单实现&#xff1a;手写数字识别的工程实践 引言 在当今…

江科大51单片机笔记【10】蜂鸣器播放提示器音乐(下)

一、蜂鸣器播放提示器 这里我们要用Key&#xff0c;Delay&#xff0c;Nixie模块 并且把Nixie.c函数里的这两句注释&#xff0c;因为之前是动态显示&#xff0c;延时后马上清零&#xff0c;现在是静态显示&#xff0c;所以需要把他注释掉 // Delay(1); // P00x00; 先验…

Nginx1.19.2不适配OPENSSL3.0问题

Nginx 1.19.2 是较老的版本&#xff0c;而 Nginx 1.21 版本已经适配 OpenSSL 3.0&#xff0c;所以建议 升级 Nginx 到 1.25.0 或更高版本&#xff1a; wget http://nginx.org/download/nginx-1.25.0.tar.gz tar -xzf nginx-1.25.0.tar.gz cd nginx-1.25.0 ./configure --prefix…

蓝桥杯 Excel地址

Excel地址 题目描述 Excel 单元格的地址表示很有趣&#xff0c;它使用字母来表示列号。 比如&#xff0c; A 表示第 1 列&#xff0c; B 表示第 2 列&#xff0c; Z 表示第 26 列&#xff0c; AA 表示第 27 列&#xff0c; AB 表示第 28 列&#xff0c; BA 表示第 53 列&#x…

免费pdf格式转换工具

基本功能 - 支持单文件转换和批量转换两种模式 - 内置PDF文件预览功能 - 支持8种常见格式转换&#xff1a;Word、Excel、JPG/PNG图片、HTML、文本、PowerPoint和ePub 单文件转换功能 - 文件选择&#xff1a;支持浏览和选择单个PDF文件 - 输出位置&#xff1a;可自定义设置输出…

css错峰布局/瀑布流样式(类似于快手样式)

当样式一侧比较高的时候会自动换行&#xff0c;尽量保持高度大概一致&#xff0c; 例&#xff1a; 一侧元素为5&#xff0c;另一侧元素为6 当为5的一侧过于高的时候&#xff0c;可能会变为4/7分部dom节点 如果不需要这样的话删除样式 flex-flow:column wrap; 设置父级dom样…

Deepseek中的MoE架构的改造:动态可变参数激活的MoE混合专家架构(DVPA-MoE)的考虑

大家好,我是微学AI,今天给大家介绍一下动态可变参数激活MoE架构(Dynamic Variable Parameter-Activated MoE, DVPA-MoE)的架构与实际应用,本架构支持从7B到32B的等多档参数动态激活。该架构通过细粒度难度评估和分层专家路由,实现“小问题用小参数,大问题用大参数”的精…

docker-compose Install reranker(fastgpt支持) GPU模式

前言BGE-重新排名器 与 embedding 模型不同&#xff0c;reranker 或 cross-encoder 使用 question 和 document 作为输入&#xff0c;直接输出相似性而不是 embedding。 为了平衡准确性和时间成本&#xff0c;cross-encoder 被广泛用于对其他简单模型检索到的前 k 个文档进行重…

基于websocket的多用户网页五子棋 --- 测试报告

目录 功能测试自动化测试性能测试 功能测试 1.登录注册页面 2.游戏大厅页面 3.游戏房间页面 自动化测试 1.使用脑图编写web自动化测试用例 2.创建自动化项目&#xff0c;根据用例通过selenium来实现脚本 根据脑图进行测试用例的编写&#xff1a; 每个页面一个测试类&am…

在 macOS 上使用 CLion 进行 Google Test 单元测试

介绍 Google Test&#xff08;GTest&#xff09;是 Google 开源的 C 单元测试框架&#xff0c;它提供了简单易用的断言、测试夹具&#xff08;Fixtures&#xff09;和测试运行机制&#xff0c;使 C 开发者能够编写高效的单元测试。 本博客将介绍如何在 macOS 上使用 CLion 配…

深度解码!清华大学第六弹《AIGC发展研究3.0版》

在Grok3与GPT-4.5相继发布之际&#xff0c;《AIGC发展研究3.0版》的重磅报告——这份长达200页的行业圣经&#xff0c;不仅预测了2025年AI技术爆发点&#xff0c;更将「天人合一」的东方智慧融入AI伦理建构&#xff0c;堪称数字时代的《道德经》。 文档&#xff1a;清华大学第…

【论文笔记】Attentive Eraser

标题&#xff1a;Attentive Eraser: Unleashing Diffusion Model’s Object Removal Potential via Self-Attention Redirection Guidance Source&#xff1a;https://arxiv.org/pdf/2412.12974 收录&#xff1a;AAAI 25 作者单位&#xff1a;浙工商&#xff0c;字节&#…

97k倍区间

97k倍区间 ⭐️难度&#xff1a;中等 &#x1f31f;考点&#xff1a;暴力&#xff0c;2017省赛 &#x1f4d6; &#x1f4da; import java.util.Scanner;public class Main {static int N 100010;public static void main(String[] args) {Scanner sc new Scanner(System.…

cursor使用经验分享(java后端服务开发向)

前言 cursor是一款基于vscode&#xff0c;并集成AI能力的代码编辑器&#xff0c;其功能包括但不限于代码生成及补全、AI对话&#xff08;能够直接将代码环境作为上下文&#xff09;、即时应用建议等等&#xff0c;是一款面向未来的代码编辑器。 对于vscode&#xff0c;最先想…

SpringBoot3—场景整合:AOT

一、AOT与JIT AOT&#xff1a;Ahead-of-Time&#xff08;提前编译&#xff09;&#xff1a;程序执行前&#xff0c;全部被编译成机器码 JIT&#xff1a;Just in Time&#xff08;即时编译&#xff09;: 程序边编译&#xff0c;边运行&#xff1b; 编译&#xff1a;源代码&am…

蓝桥与力扣刷题(蓝桥 数字三角形)

题目&#xff1a; 上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径&#xff0c;把路径上面的数加起来可以得到一个和&#xff0c;你的任务就是找到最大的和&#xff08;路径上的每一步只可沿左斜线向下或右斜线向下走&#xff09;。 输入描述…

游戏引擎学习第138天

仓库:https://gitee.com/mrxiao_com/2d_game_3 资产&#xff1a;game_hero_test_assets_003.zip 发布 我们的目标是展示游戏运行时的完整过程&#xff0c;从像素渲染到不使用GPU的方式&#xff0c;我们自己编写了渲染器并完成了所有的工作。今天我们开始了一些新的内容&#…

嵌入式学习L5D2-exec函数族和守护进程

exec函数族1 下面那个加了p环境变量就不用那个了。 输出的是系统 exec函数族2 后面不执行了 第二个参数瞎写也可以&#xff0c;但是要填 这里是说不想被替换&#xff0c;就在子进程里面执行这个。 守护进程概念 后台进程 守护进程是后台进程 一个fork了一个进程&#xff…