算法·搜索

搜索问题

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

排序和组合问题

回溯问题

图论中的搜索问题

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

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();
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

常见的限流算法有哪些?

好的&#xff0c;关于这个问题&#xff0c;我会从几个方面来回答。 首先&#xff0c;限流算法是一种系统保护策略&#xff0c;主要是避免在流量高峰导致系统被压垮&#xff0c;造成系统不可用的问题。 常见的限流算法有 5 种。 1. &#xff08;如图&#xff09;计数器限流&a…

BetaFlight源码解读01

1.打开main.c init();run(); void systemInit(void) {int ret;clock_gettime(CLOCK_MONOTONIC, &start_time);printf("[system]Init...\n");SystemCoreClock 500 * 1e6; // virtual 500MHzif (pthread_mutex_init(&updateLock, NULL) ! 0) {printf("Cr…

FPGA-按键消抖

按键消抖 1. 原理 2. 关键程序实现 always (posedge clk or negedge rst) beginif(!rst)begincnt_wait < 26d0;end else if(flag_nege || flag_pose)begincnt_wait < 26d1;end else if(cnt_wait MAX_CNT) begincnt_wait < 26d0;end else if(cnt_wait > 26d0 &am…

Qt 进度条与多线程应用、基于 Qt 的文件复制工具开发

练习1&#xff1a;Qt 进度条与多线程应用 题目描述 开发一个基于 Qt 的应用程序&#xff0c;该应用程序包含一个水平进度条&#xff08;QSlider&#xff09;&#xff0c;并且需要通过多线程来更新进度条的值。请根据以下要求完成代码&#xff1a; 界面设计&#xff1a; 使用 QS…

C语言100天练习题【记录本】

C语言经典100题&#xff08;手把手 编程&#xff09; 可以在哔哩哔哩找到 已解决的天数&#xff1a;一&#xff0c;二&#xff0c;五&#xff0c;六 下面的都是模模糊糊的 可以学学这些算法&#xff0c;我是算法白痴&#xff0c;但是我不是白痴&#xff0c;可以学&#xff…

L1G5000XTuner 微调个人小助手认知

环境配置与数据准备 本节中&#xff0c;我们将演示如何安装 XTuner。 推荐使用 Python-3.10 的 conda 虚拟环境安装 XTuner。 步骤 0. 使用 conda 先构建一个 Python-3.10 的虚拟环境 cd ~ #git clone 本repo git clone https://github.com/InternLM/Tutorial.git -b camp4 mk…

【JavaEE】阻塞队列

【JavaEE】阻塞队列 一、什么是阻塞队列&#xff1f;二、阻塞队列的特点三、阻塞队列的常用方法3.1 抛出异常3.2 有返回结果&#xff0c;不会抛出异常3.3 阻塞 四、常见的阻塞队列4.1 ArrayBlockingQueue4.2 LinkedBlockingQueue4.3 SynchronousQueue4.4 PriorityBlockingQueue…

【Python项目】基于深度学习的车辆特征分析系统

【Python项目】基于深度学习的车辆特征分析系统 技术简介&#xff1a;采用Python技术、MySQL数据库、卷积神经网络&#xff08;CNN&#xff09;等实现。 系统简介&#xff1a;该系统基于深度学习技术&#xff0c;特别是卷积神经网络&#xff08;CNN&#xff09;&#xff0c;用…

蓝桥杯备赛:每日一题

只学习不思考不记笔记假把式 这道题目的难度很难&#xff0c;当然主要的原因在于模型的转化&#xff0c;刚看的这道题也是一脸懵&#xff0c;但是转换成覆盖模型后就好了很多&#xff0c;归跟接地就是每块区域的中取最大的最少的牛覆盖天数&#xff0c;然后根据这个天数求每一块…

7. 机器人记录数据集(具身智能机器人套件)

1. 树莓派启动机器人 conda activate lerobotpython lerobot/scripts/control_robot.py \--robot.typelekiwi \--control.typeremote_robot2. huggingface平台配置 huggingface官网 注册登录申请token&#xff08;要有写权限&#xff09;安装客户端 # 安装 pip install -U …

突破极限:高性能ROCK 220A-M 工业级无人机电调深度测评 —— 无人机动力系统的核心守护者

引言 在无人机技术高速发展的今天&#xff0c;动力系统的稳定性与效率成为决定任务成败的关键。作为工业级电调领域的标杆产品&#xff0c;ROCK 220A-M 凭借其卓越的性能与多重安全设计&#xff0c;为专业级无人机应用提供了可靠的动力解决方案。本文将从技术架构、防护…

OceanBase-obcp-v3考试资料梳理

集群架构 基本概念 集群: 集群由一个或多个Region组成,Region 由一个或多个Zone组成,Zone由一个或多个OBServer组成,每个OBServer里有若干个partition的Replica。 Region: 对应物理上的一个城市或地域,当OB集群由多个Region组成时, 数据库的数据和服务能力就具备地域…

深度学习PyTorch之13种模型精度评估公式及调用方法

深度学习pytorch之22种损失函数数学公式和代码定义 深度学习pytorch之19种优化算法&#xff08;optimizer&#xff09;解析 深度学习pytorch之4种归一化方法&#xff08;Normalization&#xff09;原理公式解析和参数使用 深度学习pytorch之简单方法自定义9类卷积即插即用 实时…

Gartner发布2025年网络安全六大预测

文章目录 前言趋势1&#xff1a;生成式AI推动数据安全计划趋势2&#xff1a;管理机器身份趋势3&#xff1a;战术型AI趋势4&#xff1a;优化网络安全技术趋势5&#xff1a;扩大安全行为与文化计划的价值趋势6&#xff1a;应对网络安全倦怠 前言 Gartner发布2025年网络安全六大预…

WPS Word中英文混杂空格和行间距不一致调整方案

文章目录 问题1&#xff1a;在两端对齐的情况下&#xff0c;如何删除参考文献&#xff08;英文&#xff09;的空格问题2&#xff1a;中英文混杂行间距不一致问题问题3&#xff1a;设置中文为固定字体&#xff0c;设置西文为固定字体参考 问题1&#xff1a;在两端对齐的情况下&a…

代码随想录算法训练营第22天 | 组合 组合总和 电话号码的字母组合

77. 组合 77. 组合 - 力扣&#xff08;LeetCode&#xff09; class Solution {List<Integer> path new ArrayList<>();List<List<Integer>> result new ArrayList<>();public void backTracking(int n,int k,int startIndex){if(path.size() …

Hadoop、Hive、Spark的关系

Part1&#xff1a;Hadoop、Hive、Spark关系概览 1、MapReduce on Hadoop 和spark都是数据计算框架&#xff0c;一般认为spark的速度比MR快2-3倍。 2、mapreduce是数据计算的过程&#xff0c;map将一个任务分成多个小任务&#xff0c;reduce的部分将结果汇总之后返回。 3、HIv…

从0开始的操作系统手搓教程21:进程子系统的一个核心功能——简单的进程切换

目录 具体说说我们的简单RR调度 处理时钟中断处理函数 调度器 schedule switch_to 我们下面&#xff0c;就要开始真正的进程切换了。在那之前&#xff0c;笔者想要说的是——我们实现的进程切换简单的无法再简单了——也就是实现一个超级简单的轮询调度器。 每一个进程按照…

EP 架构:未来主流方向还是特定场景最优解?

DeepSeek MoE架构采用跨节点专家并行&#xff08;EP&#xff09;架构&#xff0c;在提升推理系统性能方面展现出巨大潜力。这一架构在发展进程中也面临诸多挑战&#xff0c;其未来究竟是会成为行业的主流方向&#xff0c;还是仅适用于特定场景&#xff0c;成为特定领域的最优解…

win11编译llama_cpp_python cuda128 RTX30/40/50版本

Geforce 50xx系显卡最低支持cuda128&#xff0c;llama_cpp_python官方源只有cpu版本&#xff0c;没有cuda版本&#xff0c;所以自己基于0.3.5版本源码编译一个RTX 30xx/40xx/50xx版本。 1. 前置条件 1. 访问https://developer.download.nvidia.cn/compute/cuda/12.8.0/local_…