浙江大学数据结构MOOC-课后习题-第六讲-图2 Saving James Bond - Easy Version

news2024/11/17 9:49:01

题目汇总
浙江大学数据结构MOOC-课后习题-拼题A-代码分享-2024

题目描述

在这里插入图片描述

测试点

在这里插入图片描述

思路分享

①解题思路概览
我的想法是,先建立一个图,然后再利用DFS或者BFS来遍历判断当前顶点能否跳到岸上去
②怎么建图?

  • 首先要考虑采用什么数据结构来存储图?
    由于题目中的坐标是存在负数的,所有坐标不好和邻接矩阵数组下标一一对应,因此我选择使用邻接表来存储图

  • 接下来要考虑的是,怎么来建立顶点?
    我这里是将所有鳄鱼,以及湖心都作为了节点,因此建立的顶点数要在输入的N的基础上再加1

  • 那么怎么建立边呢?
    我们要注意到题目中有一个条件是james的跳跃距离D,只要他目前所处的位置到任意一个顶点的距离小于等于D,那么他就能跳过去,然后就可以建立一条边(后续判断是否上岸也是根据这个D来进行判断)(本考研鼠鼠对上岸这个词有点敏感了hhhh)

但需要注意一点,由于我把湖心也作为了顶点,所以它和鳄鱼之间也要建立边。它和鳄鱼之间的距离的计算公式中,还要减去中心岛的半径(题目中是7.5

③怎么遍历所有节点呢
遍历所有节点有两种方式:BFS或者DFS;由于我想到BFS要使用队列,感觉会麻烦一点,所以选择了DFS。
DFS的代码逻辑就是:

  • 先判断当前节点是否已访问过;(因此要建立一个数组来存储当前顶点是否被访问过)
  • 再访问当前节点(在本题中这一步就是判断是否能够逃脱,具体怎么判断请看后文)
  • 然后遍历访问当前节点的所有邻接点(这一步使用循环+DFS递归)

④怎么判断是否能够逃脱上岸呢
首先我们以湖心为坐标原点,画一个xy坐标系,x的取值范围:[-50,50],y的取值范围:[-50,50];
由此我们可以得到一个边界,我们要是能够从当前顶点跳到边界,那么就代表逃脱成功了,那么怎么计算呢?
其实就是利用以下几个式子abs(50-x)、abs(50-y)、abs(-50-x)、abs(-50-y)(这就是当前顶点到4条边界的距离)。将这几个值和上文提到的D进行比较,如果值小于等于D,那么就能成功逃脱啦!

⑤其他注意事项
把湖心作为顶点后,记得在创建数组时,数组的大小要在题目的输入N的基础上加1

代码展示

#include <cmath>
#include <cstdlib>
#include <iostream>
#define MAXSIZE 100
#define r 7.5

typedef int pos;
int D;
int check[MAXSIZE + 1] = { 0 };	//检查节点是否被访问过
int res = 0;
/* 顶点 */
struct vertex
{
	pos x, y;
};

/* 边 */
struct ENode
{
	vertex V1, V2;
};
typedef ENode* ptrToENode;
typedef ptrToENode Edge;

/* 邻接表的链表节点 */
struct AdjNode
{
	vertex AdjV;	/* 邻接点位置 */
	AdjNode* next;
};
typedef AdjNode* ptrToAdjNode;


/* 邻接表的表头数组 */
typedef struct VNode
{
	ptrToAdjNode FirstEdge;
	vertex _POS;
}AdjList[MAXSIZE + 1];

/* 图的定义 */
struct GNode
{
	int Nv;	/* 顶点数 */
	int Ne;	/* 边数 */
	AdjList G;	//邻接表
};
typedef GNode* ptrToGNode;
typedef ptrToGNode LGraph;

/* 创建并初始化一个图 */
LGraph creatGraph(int Nv)
{	
	vertex V;
	LGraph graph = (LGraph)malloc(sizeof(GNode));
	graph->Nv = Nv;
	graph->Ne = 0;
	graph->G[0]._POS = { 0 , 0 };
	graph->G[0].FirstEdge = NULL;
	for (int i = 1; i < graph->Nv; i++)
	{	
		std::cin >> V.x >> V.y;		//将鳄鱼位置保存在表头数组中
		graph->G[i]._POS = V;
		graph->G[i].FirstEdge = NULL;
	}
	return graph;
}
/* 查找V在表头数组中的下标 */
int findIndex(LGraph Graph, vertex V)
{
	for (int i = 0; i < Graph->Nv; i++)
	{
		if (Graph->G[i]._POS.x == V.x && Graph->G[i]._POS.y == V.y)
			return i;
	}
}
/* 向图中插入一条边 */
void insertEdge(LGraph Graph, Edge E)
{
	vertex V = E->V1;
	vertex W = E->V2;
	int i = findIndex(Graph, V);
	/* 为W建立新的邻接点空间,并将其插到V的表头 */
	ptrToAdjNode newNode = (ptrToAdjNode)malloc(sizeof(AdjNode));
	newNode->AdjV = W;
	newNode->next = Graph->G[i].FirstEdge;
	Graph->G[i].FirstEdge = newNode;
	Graph->Ne++;
}
/* 检查当前节点能否逃脱 */
bool checkOut(vertex V)
{
	if (abs(-50 - V.x) <= D) return true;
	else if (abs(-50 - V.y) <= D) return true;
	else if (abs(50 - V.x) <= D) return true;
	else if (abs(50 - V.y) <= D) return true;
	else return false;
}



LGraph buildGraph(int N)
{	
	/* 创建图并初始化顶点 */
	LGraph Graph = creatGraph(N);
	vertex V, W;
	/* 建立边 */
	//遍历所有边,在遍历过程中,检查是否有能够建立连接的边
	for (int i = 0; i < Graph->Nv; i++)
	{	
		V = Graph->G[i]._POS;
		for (int j = 0; j < Graph->Nv; j++)
		{	
			W = Graph->G[j]._POS;

			if (i == j) continue;
			else if (i == 0 && j != 0)
			{
				//鳄鱼所在的顶点W到中心岛中心的距离 - 中心岛半径r <= james跳跃距离,则建立边
				double d = sqrt(pow(V.x - W.x, 2) + pow(V.y - W.y, 2)) - r;
				if (d <= D)
				{
					ptrToENode newEdge = (ptrToENode)malloc(sizeof(ENode));
					newEdge->V1 = V;
					newEdge->V2 = W;
					insertEdge(Graph, newEdge);
				}
			}
			else if (j == 0 && i != 0)
			{
				//鳄鱼所在的顶点W到中心岛中心的距离 - 中心岛半径r <= james跳跃距离,则建立边
				double d = sqrt(pow(V.x - W.x, 2) + pow(V.y - W.y, 2)) - r;
				if (d <= D)
				{
					ptrToENode newEdge = (ptrToENode)malloc(sizeof(ENode));
					newEdge->V1 = V;
					newEdge->V2 = W;
					insertEdge(Graph, newEdge);
				}
			}
			else
			{
				//两点的距离小于james跳跃距离,则建立边
				double d = sqrt(pow(V.x - W.x, 2) + pow(V.y - W.y, 2));
				if (d <= D)
				{
					ptrToENode newEdge = (ptrToENode)malloc(sizeof(ENode));
					newEdge->V1 = V;
					newEdge->V2 = W;
					insertEdge(Graph, newEdge);
				}
			}
		}
	}
	return Graph;
}

int visit[MAXSIZE + 1] = { 0 };
void DFS(LGraph Graph, vertex V)
{	
	ptrToAdjNode W;
	/* 检查当前顶点是否被访问过 */
	int i = findIndex(Graph, V);
	if (visit[i] != 0) return;
	visit[i] = 1;

	/* 检查当前顶点能否使james上岸 */
	if (checkOut(V))
	{
		res = 1;	//存储结果的变量	1:表示成功逃脱
		return;
	}
	/* 访问V的所有邻接点 */
	for (W = Graph->G[i].FirstEdge; W != NULL; W = W->next)
	{	
		i = findIndex(Graph, W->AdjV);
		if (visit[i] != 1)
			DFS(Graph, W->AdjV);
	}
}

int main()
{
	int N;
	std::cin >> N >> D;
	LGraph Graph = buildGraph(N + 1);
	DFS(Graph, Graph->G[0]._POS);
	if (res)
		std::cout << "Yes";
	else
		std::cout << "No";
	return 0;
}

心路历程

不看教程做题效率好低啊~~~~~~
一天做了一道,又是被自己菜哭的一天

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

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

相关文章

计算机网络导论

网络结构的演变 网状结构 最开始的网络&#xff0c;主机之间都是两两相连 好处 这样连接&#xff0c;好处是安全性比较高&#xff08;A与B之间的连线断了&#xff0c;可以绕一下C&#xff09;&#xff1b; 另外通信不需要互相等待&#xff08;没有中间交换设备&#xff0c;所…

yolov8+ROS+ubuntu18.04——学习记录

参考文献 1.Ubuntu配置Yolov8环境并训练自己的数据集 ROS实时运行 2.https://juejin.cn/post/7313979467965874214 前提&#xff1a; 1.CUDA和Anaconda&#xff0c;PyTorch 2.python>3.8 一、创建激活环境&#xff0c;安装依赖 1.创建虚拟环境 conda create -n yol…

【Qt Creator】跨平台的C++图形用户界面应用程序开发框架---QT

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 1.互联网的核心岗位以及职…

一个基于预训练的DenseNet121模型的人脸年龄分类系统

这篇文章采用预训练的DenseNet121模型并使用自定义的数据集类和自定义的类似正态分布的标签平滑策略来训练了一个人脸年龄分类模型&#xff0c;最后基于这个模型用tk实现了一个娱乐向的小系统。 数据集展示&#xff1a; 两个文件夹&#xff0c;分别是训练集和测试集&#xff0…

空压机的热回收原理介绍

空压机运行时会产生大量的压缩热&#xff0c;通常这部分能量通过机组的风冷或水冷系统释放到大气当中。压缩机的热回收是持续降低空气系统损耗&#xff0c;提高客户生产力的必要手段。 余热回收的节能技术目前研究很多&#xff0c;但大多只针对喷油螺杆式空压机的油路改造而言…

【Linux】使用pip3安装pexpect,解决报错:the ssl module in Python is not available

pip3是python3的包管理工具&#xff0c;安装、卸载、更新等管理python包。 pexpect是其中一个python库&#xff0c;用于自动化与终端交互。 centos7使用pip3安装pexpect&#xff0c;报错&#xff1a; pip3 install pexpect 原因&#xff1a;使用python3解释器导入ssl库检查ss…

【网络协议】划重点啦!TCP与UDP的重点面试题!!!

1. 为什么建立TCP连接是三次握手&#xff0c;而关闭连接却是四次挥手呢&#xff1f; 这是因为服务端的 LISTEN 状态下的 SOCKET 当收到 SYN 报文的建连请求后&#xff0c;它可以把 ACK和 SYN&#xff08;ACK 起应答作用&#xff0c; 而 SYN 起同步作用&#xff09; 放在一个报文…

建立FTP服务器

文章目录 建立FTP服务器1. 使用VMware安装CentOS 7虚拟机。2. 安装完虚拟机后&#xff0c;进入虚拟机&#xff0c;修改网络配置&#xff08;onboot改为yes&#xff09;并重启网络服务&#xff0c;查看相应IP地址&#xff0c;并使用远程连接软件进行连接。3.配置yum源&#xff0…

图形学概述

图形学应用 游戏 游戏的画面好坏如何鉴定呢&#xff1f; 看游戏画面是否够亮&#xff1a;渲染中全局光照的好坏 《只狼》 为什么卡通游戏画面看起来是卡通的呢&#xff1f; 《无主之地3》 这些都是图形学需要着手解决的问题 电影 电影《黑客帝国》的特效也是通过计算机…

AI大模型探索之路-实战篇9:探究Agent智能数据分析平台的架构与功能

系列篇章&#x1f4a5; AI大模型探索之路-实战篇4&#xff1a;深入DB-GPT数据应用开发框架调研 AI大模型探索之路-实战篇5&#xff1a;探索Open Interpreter开放代码解释器调研 AI大模型探索之路-实战篇6&#xff1a;掌握Function Calling的详细流程 AI大模型探索之路-实战篇7…

OWASP top10--SQL注入(三、手工注入)

目录 access数据库 手工注入过程&#xff1a; 猜解数据库表名 猜解数据库表名里面的字段 猜解字段内容 SQL注入中的高级查询 mssql数据库 手工注入过程&#xff1a; sa权限 ​编辑dbowner权限 public权限 mysql数据库 1、对服务器文件进行读写操作(前提条件) 需要知…

二叉树顺序结构的实现(堆)

二叉树的基本概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。 有一个特殊的结点&#xff0c;称为根结…

浙江大学数据结构MOOC-课后习题-第九讲-排序1 排序

题目汇总 浙江大学数据结构MOOC-课后习题-拼题A-代码分享-2024 题目描述 文章目录 冒泡排序插入排序希尔排序堆排序归并排序 冒泡排序 void buble_Sort() { int A[MAXSIZE];int N;std::cin >> N;for (int i 0; i < N; i)std::cin >> A[i];bool flag false;i…

滑动窗口-java

主要通过单调队列来解决滑动窗口问题&#xff0c;得到滑动窗口中元素的最大值和最小值。 目录 前言 一、滑动窗口 二、算法思路 1.滑动窗口 2.算法思路 3.代码详解 三、代码如下 1.代码如下 2.读入数据 3.代码运行结果 总结 前言 主要通过单调队列来解决滑动窗口问题&#xff…

(免费领源码)java#SSM#mysql第三方物流系统37852-计算机毕业设计项目选题推荐

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作…

EasyCode生成的SQL语句中无逗号分隔

EasyCode生成的SQL语句中无逗号分隔 EasyCode是一款非常好用的插件&#xff0c;可以帮助我们生成相关的一些代码&#xff0c;但是在生成SQL对应的xml文件之后&#xff0c;发现语句中多个字段之间没有逗号分隔&#xff0c;而是直接连在了一起。接下来&#xff0c;让我们一起去解…

Kubernetes——Kubectl详解

目录 前言 一、陈述式资源管理方法 二、Kubectl命令操作 1.查 1.1kubectl version——查看版本信息 1.2kubectl api-resources——查看资源对象简写 1.3kubectl cluster-info——查看集群信息 1.4配置Kubectl补全 1.5journalctl -u kubelet -f——查看日志 1.6kubec…

C-数据结构-树状存储基本概念

‘’’ 树状存储基本概念 深度&#xff08;层数&#xff09; 度&#xff08;子树个数&#xff09; 叶子 孩子 兄弟 堂兄弟 二叉树&#xff1a; 满二叉树&#xff1a; 完全二叉树&#xff1a; 存储&#xff1a;顺序&#xff0c;链式 树的遍历&#xff1a;按层遍历&#xff0…

Qt for android 串口库使用

简介 由于Qt for android并没有提供android的串口执行方案&#xff0c;基于需要又懒得自己去造轮子&#xff0c; 使用开源的 usb-serial-for-android 库进行串口访问读写。 如果有自己的需要和库不满足的点&#xff0c;可以查看库的底层调用的Android相关API C/C 串口库 对应…

驱动开发:内核MDL读写进程内存

100编程书屋_孔夫子旧书网 MDL内存读写是最常用的一种读写模式,通常需要附加到指定进程空间内然后调用内存拷贝得到对端内存中的数据,在调用结束后再将其空间释放掉,通过这种方式实现内存读写操作,此种模式的读写操作也是最推荐使用的相比于CR3切换来说,此方式更稳定并不会…