首页 > 其他分享 >KDY----BFS_宽度优先搜索习题

KDY----BFS_宽度优先搜索习题

时间:2024-06-09 21:29:22浏览次数:14  
标签:---- vis dep BFS int 数组 习题 方块 描述

题目由可达鸭提供,本篇够   字,阅读时注意休息和暂停。

一、课时提交情(AC情况)

T1、武士风度的牛   100/100(老师带着做的。)

T2、抓住那头牛 100/100

T3、仙岛求药    100/100

T4、The Castle  0/100(时间不够了,就看了看题目。)

二、目录

T1、

武士风度的牛

T2、

抓住那头牛

T3、

仙岛求药

T4、

The Castle

三、讲解

T1、

时间限制:1秒        内存限制:128M

题目描述

农民 John 有很多牛,他想交易其中一头被 Don 称为 The Knight 的牛。这头牛有一个独一无二的超能力,在农场里像 Knight 一样地跳(就是我们熟悉的象棋中马的走法)。虽然这头神奇的牛不能跳到树上和石头上,但是它可以在牧场上随意跳,我们把牧场用一个 x,y 的坐标图来表示。这头神奇的牛像其它牛一样喜欢吃草,给你一张地图,上面标注了 The Knight 的开始位置,树、灌木、石头以及其它障碍的位置,除此之外还有一捆草。现在你的任务是,确定 The Knight 要想吃到草,至少需要跳多少次。The Knight 的位置用 K 来标记,障碍的位置用 * 来标记,草的位置用 H 来标记。

这里有一个地图的例子:

11 | . . . . . . . . . .
10 | . . . . * . . . . .
9   | . . . . . . . . . .
8   | . . . * . * . . . .
7   | . . . . . . . * . .
6   | . . * . . * . . . H
5   | * . . . . . . . . .
4   | . . . * . . . * . .
3   | . K . . . . . . . .
2   | . . . * . . . . . *
1   | . . * . . . . * . .
0   ----------------------
                              1
0 1 2 3 4 5 6 7 8 9 0

The Knight 可以按照下图中的 A,B,C,D… 这条路径用 5 次跳到草的地方(有可能其它路线的长度也是 5):

11 | . . . . . . . . . .
10 | . . . . * . . . . .
9   | . . . . . . . . . .
8   | . . . * . * . . . .
7   | . . . . . . . * . .
6   | . . * . . * . . . F<
5   | * . B . . . . . . .
4   | . . . * C . . * E .
3   | .>A . . . . D . . .
2   | . . . * . . . . . *
1   | . . * . . . . * . .
0   ----------------------
                              1
0 1 2 3 4 5 6 7 8 9 0

输入描述

第一行: 两个数,表示农场的列数(< =150)和行数(< =150) 第二行..结尾: 如题目描述的图。

输出描述

一个数,表示跳跃的最小次数。

样例

输入

10 11
..........
....*.....
..........
...*.*....
.......*..
..*..*...H
*.........
...*...*..
.K........
...*.....*
..*....*..

输出

5

提示

Hint:这类问题可以用一个简单的先进先出表(队列)来解决。

首先可以看到是最小次数问题(最小步数),所以用BFS来解决。

题解思路:

首先输入整个地图,再输入时也要判断起点和终点即K和H。边判断,边记录k和h的坐标(也就是说AC代码中的sx,sy,ex,ey)。然后就要进行BFS首先先标记,然后将x和y入队。一般的是默认他的头是一步如果说输出比样例大一,那么将这行注释掉,然后就是比较正常的是BFS了,然后就是f小于r就是说队列不为空,然后存一下这个队列的头,头进行查找与他所有相关的邻接点,最后将队头出队。

//AC代码中的部分变量名称用法详解

1.结构体数组q,队列一共是有22500个点(因为图中最大是一个150×150的)。

2.char类型数组a,保存地图时使用150x150的为了防止下标越界各加了5

3.f和r是q队列的头和尾;dep数组储存最小步数

4.dx ,dy就是方向数组

5.vis防止重搜

AC代码如下:

#include<iostream>
using namespace std;
struct dl{
	int h,l;
}q[22500];
char a[155][155];
int f,r,dep[155][155];
int dx[]={-2,-2,-1,-1,1,1,2,2},dy[]={-1,1,-2,2,-2,2,-1,1};
bool vis[155][155];
int m,n,sx,sy,ex,ey;
void BFS(int x,int y){
	vis[x][y]=1;
	q[r].h=x;
	q[r++].l=y;
//	dep[x][y]=1;
	while(f<r){
		int px=q[f].h,py=q[f].l;
		for (int i=0;i<8;i++){
			int nx=px+dx[i],ny=py+dy[i];
			if (nx>=1&&nx<=n&&ny>=1&&ny<=m){
				if (vis[nx][ny]==0&&a[nx][ny]!='*'){
					vis[nx][ny]=1;
					q[r].h=nx;
					q[r++].l=ny;
					dep[nx][ny]=dep[px][py]+1;
				}
			}
		}
		f++;
	}
}
int main(){
	cin>>m>>n;
	for (int i=1;i<=n;i++){
		for (int j=1;j<=m;j++){
			cin>>a[i][j];
			if (a[i][j]=='K'){
				sx=i;
				sy=j;
			}
			if (a[i][j]=='H'){
				ex=i;
				ey=j;
			}
		}
	}
	BFS(sx,sy);
	cout<<dep[ex][ey];
	return 0; 
}

T2、

时间限制:1秒        内存限制:128M

题目描述

农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N(0≤N≤100000),牛位于点K(0≤K≤100000)。农夫有两种移动方式: 

1、从X移动到X-1或X+1,每次移动花费一分钟 

2、从X移动到2*X,每次移动花费一分钟 

假设牛没有意识到农夫的行动,站在原地不动。农夫最少要花多少时间才能抓住牛?

输入描述

两个整数,N和K。

输出描述

一个整数,农夫抓到牛所要花费的最小分钟数。

样例

输入
5 17
输出
4

题解思路:

此题目求解的是最小分钟数,也就是说最小步数。所以说此题还是BFS的最小步数问题。

其中题目描述中标黄的就是提示你方向数组该怎么写它是在一个数轴上,但是它不能用数学模拟的方式去模拟它。因为一些数学模拟可能会忽略某种情况,比如说减一再乘二比直接加一要简单。所以说这实际上就可以看成一棵树。如下图(本人没有特别多的美术细胞,请见谅):

就是他判断就是是加1-1还是二乘x这三种情况将其看为一棵树。

 //AC代码中的部分变量名称用法详解

1.结构体数组q,队列一共是有22500个点(因为图中最大是一个150×150的)。

2.char类型数组a,保存地图时使用150x150的为了防止下标越界各加了5

3.f和r是q队列的头和尾;dep数组储存最小步数

4.dx ,dy就是方向数组

5.vis防止重搜

AC代码如下:

#include<iostream>
using namespace std;
const int N=1e5;
int q[N+5],n,k,dep[N+5];
int dx[]={-1,1,2};
int f,r;
bool vis[N+5];
void bfs(int x){
	vis[x]=1;
	q[r++]=x;
	//dep[x]=1;
	while(f<r){
		int px=q[f];
		for (int i=0;i<3;i++){
			int nx;
			if (i<2){
				nx=px+dx[i];
			}
			else{
				nx=px*dx[i];
			}
			if (nx>=0&&nx<=N){
				if (vis[nx]==0){
					vis[nx]=1;
					q[r++]=nx;
					dep[nx]=dep[px]+1;;
				}
			}
		}
		f++;
	}
}
int main(){
	cin>>n>>k;
	bfs(n);
	cout<<dep[k];
	return 0; 
}

T3、

时间限制:1秒        内存限制:128M

题目描述

少年李逍遥的婶婶病了,王小虎介绍他去一趟仙灵岛,向仙女姐姐要仙丹救婶婶。叛逆但孝顺的李逍遥闯进了仙灵岛,克服了千险万难来到岛的中心,发现仙药摆在了迷阵的深处。迷阵由M×N个方格组成,有的方格内有可以瞬秒李逍遥的怪物,而有的方格内则是安全。现在李逍遥想尽快找到仙药,显然他应避开有怪物的方格,并经过最少的方格,而且那里会有神秘人物等待着他。现在要求你来帮助他实现这个目标。 

下图 显示了一个迷阵的样例及李逍遥找到仙药的路线。

输入描述

输入有多组测试数据. 每组测试数据以两个非零整数 M 和 N 开始,两者均不大于20。M 表示迷阵行数, N 表示迷阵列数。接下来有 M 行, 每行包含N个字符,不同字符分别代表不同含义: 

1)‘@’:少年李逍遥所在的位置; 

2)‘.’:可以安全通行的方格; 

3)‘#’:有怪物的方格; 

4)‘*’:仙药所在位置。 当在一行中读入的是两个零时,表示输入结束。

输出描述

对于每组测试数据,分别输出一行,该行包含李逍遥找到仙药需要穿过的最少的方格数目(计数包括初始位置的方块)。如果他不可能找到仙药, 则输出 -1。

样例

输入

8 8
.@##...#
#....#.#
#.#.##..
..#.###.
#.#...#.
..###.#.
...#.*..
.#...###
6 5
.*.#.
.#...
..##.
.....
.#...
....@
9 6
.#..#.
.#.*.#
.####.
..#...
..#...
..#...
..#...
#.@.##
.#..#.
0 0

输出

10
8
-1

题解思路:

此题实际上思路实际上是大概跟第一个题是一样一样的,在此本人就不过多的赘述了。

讲一下注意事项:

1.就是他有多组样例的输入,一定要把vis数组,dep数组,q数组均清零。

2.一定注意,一定注意,要把f和r也要清零。

AC代码如下:

#include<iostream>
#include<cstring>
using namespace std;
struct dl{
	int h,l;
}q[4005];
char a[25][25];
int f,r,dx[]={-1,0,0,1},dy[]={0,-1,1,0};
int n,m,dep[25][25];
bool vis[25][25];
int sx,sy,ex,ey;
void bfs(int x,int y){
	q[r].h=x;
	q[r++].l=y;
	vis[x][y]=1;
	//dep[x][y]=1;
	while(f<r){
		int px=q[f].h,py=q[f].l;
		for (int i=0;i<4;i++){
			int nx=px+dx[i],ny=py+dy[i];
			if (nx>=1&&nx<=m&&ny>=1&&ny<=n){
				if (vis[nx][ny]==0&&a[nx][ny]!='#'){
					q[r].h=nx;
					q[r++].l=ny;
					vis[nx][ny]=1;
					dep[nx][ny]=dep[px][py]+1;	
				}
			}
		}
		f++; 
	}
}
int main(){
	while (cin>>n>>m){
		if (n==0&&m==0){
			break;
		}
		memset(vis,0,sizeof(vis));
		memset(dep,0,sizeof(dep));
		memset(q,0,sizeof(q));
		f=0;
		r=0;
		for (int i=1;i<=n;i++){
			for (int j=1;j<=m;j++){
				cin>>a[i][j];
				if (a[i][j]=='@'){
					sx=i;
					sy=j;
				}
				if (a[i][j]=='*'){
					ex=i;
					ey=j;
				}
			}
		}
		bfs(sx,sy);
		if (dep[ex][ey]==0){
			cout<<"-1"<<endl;
		}
		else{
			cout<<dep[ex][ey]<<endl;
		}
	}
	return 0;
}

T4、

时间限制:1秒        内存限制:128M

题目描述

一座城堡被分成m*n个方块(m≤50,n≤50),每个方块可有0~4堵墙(0表示无墙)。下面示出了建筑平面图:

图中的加粗黑线代表墙。几个连通的方块组成房间,房间与房间之间一定是用黑线(墙)隔开的。 

现在要求你编一个程序,解决以下2个问题: 

1、该城堡中有多少个房间? 

2、最大的房间有多大?

输入描述

平面图用一个数字表示一个方块(第1个房间用二进制1011表示,0表示无东墙,用十进制11表示)。 

第一行一个整数m(m≤50),表示房子南北方向的长度。 

第二行一个整数n(n≤50),表示房子东西方向的长度。

后面的m行,每行有n个整数,每个整数都表示平面图对应位置的方块的特征。每个方块中墙的特征由数字P来描述(0≤P≤15)。数字P是下面的可能取的数字之和: 

1(西墙 west) 

2(北墙 north) 

4(东墙 east) 

8(南墙 south) 

室内的墙被定义两次: 例如方块(1,1)中的南墙也被位于其南面的方块(2,1)定义了一次。 

建筑中至少有两个房间。

输出描述

第1行:一个整数,表示房间总数; 

第2行:一个整数,表示最大房间的面积(方块数)。

样例

输入

4
7
11 6 11  6  3 10  6
7  9  6 13  5 15  5
1 10 12  7 13  7  5
13 11 10 8 10 12 13

输出

5
9

题解思路:

此期实际上可以就去看我那个最大人工岛DFS的补题报告。此题实际上跟BFS一点儿边都不沾。实际上就是利用多次的DFS求它每一块的连通区域。记录的同时比较每一块儿联通区域的大小,最后输出有几块儿连通区域,然后输出最大的那一块儿。

AC代码如下:

#include<iostream>
using namespace std;
int m,n,a[55][55][5],cnt,maxx,temp,cnt1;
bool vis[55][55];
int dx[]={0,-1,0,1},dy[]={-1,0,1,0};
void dfs(int x,int y){
	vis[x][y]=1;
	temp++;
	for (int i=0;i<4;i++){
		int nx=x+dx[i],ny=y+dy[i];
		if (nx>=1&&nx<=m&&ny>=1&&ny<=n){
			if (vis[nx][ny]==0&&a[x][y][i]==0){
				dfs(nx,ny);
			}
		}
	}
}
int main(){
	int t;
	cin>>m>>n;
	for (int i=1;i<=m;i++){
		for (int j=1;j<=n;j++){
			cin>>t;
			cnt1=0;
			while (t!=0){
				a[i][j][cnt1]=t%2;
				t=t/2;
				cnt1++;
			}
		}
	}
	for (int i=1;i<=m;i++){
		for (int j=1;j<=n;j++){
			if (vis[i][j]==0){
				temp=0;
				dfs(i,j);
				cnt++;
				if (maxx<temp){
					maxx=temp;
				}
			}
		}
	}
	cout<<cnt<<endl<<maxx;
	return 0;
}

最后还有一个小投票,欢迎投一下:

标签:----,vis,dep,BFS,int,数组,习题,方块,描述
From: https://blog.csdn.net/gjh870411/article/details/139559864

相关文章

  • 基于SpringBoot+Vue+uniapp的网络小说微信小程序的详细设计和实现(源码+lw+部署文档+
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......
  • 基于SpringBoot+Vue+uniapp的校友林微信小程序的详细设计和实现(源码+lw+部署文档+讲
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......
  • 软件测试————Bug的定义及生命周期
    目录一、Bug的定义二、Bug的生命周期   三、Bug的等级划分一、Bug的定义    定义:⼀个计算机bug指在计算机程序中存在的⼀个错误(error)、缺陷(flaw)、疏忽(mistake)或者故障(fault),这些bug使程序⽆法正确的运⾏。二、Bug的生命周期    1、New(新......
  • HTTP与HTTPS的区别
    HTTP和HTTPS的主要区别体现在以下几个方面:1.安全性HTTP协议以明文方式发送内容,不提供任何方式的数据加密。这意味着如果攻击者截取了Web浏览器和网站服务器之间的传输报文,他们可以直接读懂其中的信息。相比之下,HTTPS协议则通过SSL/TLS协议进行加密传输,这种加密方式可以保护数据......
  • NSCC集群使用笔记
    1.账号申请如果是NUS,NTU或者ASTAR的学生,可以直接用自己的学校ID登录。登录不上的话可以发邮件联系nscc工作人员即可,基本上第二天就会回复解决。2.VSCode连接账号申请下来后进官网设置你的sshkey之类的东西就可以登录了。第一次登录成功后,可以参考这篇文章设置ssh......
  • 高考假集训总结(6.9)
    6.9今天依然是单调队列优化dp和斜率优化dp(只不过斜率优化的题还没开始做,具体原因下面讲)突然发现自己学得越多,忘得越多,都想不起来单调队列怎么用了,于是又花一上午跑回去看了单调队列的题并调了一上午的t1暴力做法,现在终于可以将两者融会贯通也就是成功实现了单调队列优化dp不......
  • Spring Boot入坑-11-打包和发布
    准备环境Java运行环境Java的应用多发布于Linux环境,如CentOS7部署应用前,在远程Linux主机或虚拟机上,需要安装JDK或JRE,使用如下命令安装一个OpenJDKyum-yinstalljava-1.8.0-openjdk数据库环境一般应用都需要有数据库支持,像MySQL,但一般在企业中会由运维或DBA提供......
  • OpenAI 推出适用于 .NET 的 OpenAI 库
    微软宣布面向.NET开发人员官方OpenAI库。OpenAI库支持完整的OpenAIAPI和OpenAI的最新旗舰模型GPT-4o,该模型可以实时推理音频、视觉和文本。OpenAI.NETAPI库目前提供第一个测试版,可通过NuGet 访问。OpenAI.NETAPI库是微软与OpenAI合作的成果,它提供了从.N......
  • .NET借助虚拟网卡实现一个简单异地组网工具
    由于工作需要,经常需要远程客户的服务器,但是并不是所有服务器都能开外网端口,使用向日葵等软件终究还是不太方便,于是找了很多工具,包括zerotier等,但是由于服务器在国外等有时候还不同,于是开始自己想办法研究一个属于自己的组网工具,最后找到snltty大佬的 https://github.com/snltty......
  • Spring Boot入坑-12-项目实战
    目标掌握后端项目整体架构搭建,掌握从0到1构建一个完整项目巩固已学习的后端技术,覆盖Java基础、SpringBoot的主要课程内容,包括但不限:序列化、反射、注解、泛型、Lambda、Stream、REST、Interceptor、数据访问、Swagger等等一些扩展内容的学习,比如登录、密码加密、项目部......