当前位置: 首页 > news >正文

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

题目汇总
浙江大学数据结构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.5typedef 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";elsestd::cout << "No";return 0;
}

心路历程

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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • I.MX6ULL Linux 点灯实验理论及汇编点灯
  • 深度学习-转置卷积
  • 月薪5万是怎样谈的?
  • 【ARMv7-A】——WFE(wait for event)
  • 2024 前端面试每日1小时
  • JAVA自制小游戏之推箱子
  • 光伏组件积灰检测系统
  • 【代码】自定义函数
  • 数据治理与数据提取:解锁信息价值的双钥匙
  • 计算机网络——物理层
  • img标签添加::before ::after 伪元素无效,伪元素增加:hover伪类无效
  • java项目之飘香水果购物网站(springboot+vue+mysql)
  • 树莓派4B 学习笔记1:TF卡系统盘烧录_初次启动_远程端连接配置
  • 【高阶数据结构(七)】B+树, 索引原理讲解
  • 多态(C++)
  • 【前端学习】-粗谈选择器
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • emacs初体验
  • JAVA 学习IO流
  • React组件设计模式(一)
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 浅谈web中前端模板引擎的使用
  • 实现简单的正则表达式引擎
  • 实战|智能家居行业移动应用性能分析
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 网页视频流m3u8/ts视频下载
  • 再谈express与koa的对比
  • 转载:[译] 内容加速黑科技趣谈
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • # .NET Framework中使用命名管道进行进程间通信
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #pragma multi_compile #pragma shader_feature
  • $.ajax中的eval及dataType
  • (STM32笔记)九、RCC时钟树与时钟 第二部分
  • (zt)最盛行的警世狂言(爆笑)
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (过滤器)Filter和(监听器)listener
  • (四)软件性能测试
  • (循环依赖问题)学习spring的第九天
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转)使用VMware vSphere标准交换机设置网络连接
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • .gitignore文件设置了忽略但不生效
  • .NET Core/Framework 创建委托以大幅度提高反射调用的性能
  • .NET 分布式技术比较
  • .Net 基于MiniExcel的导入功能接口示例
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)
  • .NET企业级应用架构设计系列之结尾篇
  • .NET学习教程二——.net基础定义+VS常用设置
  • @RequestBody的使用