您的位置:首页 > 理论基础 > 数据结构算法

中国大学MOOC-数据结构基础习题集、05-2、Saving James Bond - Easy Version

2015-01-03 11:02 471 查看
题目链接:http://www.patest.cn/contests/mooc-ds/05-2

题目分析:这是一道考察图的深度优先遍历的一道题,题目的背景是007。相信听过陈老师的课,都对这道题的背景有所了解。如果没有认真听或者忘记的话,我再重复一次好了。

  007处在孤岛上,孤岛的半径为15米,孤岛的范围就是[±15, ±15]。池塘的范围是[±50, ±50],池塘中有若干条鳄鱼,他的数量以及坐标都通过输入给了出来。007的跳跃距离也通过输入给了出来。要求的计算出是007能否通过不断“踩鳄鱼”来逃出生天呢?

  输入:鳄鱼的数量+007的跳跃半径+鳄鱼的坐标。

  输出:Yes能逃出,No不能逃出。

特别说明:

  1. 不需要建立图这种数据结构,只需要用数组把坐标信息存起来就可以了。

  2. 需要有一个额外的visited数组,来存储结点是否被访问过。

  3. 孤岛也是一个结点,它的坐标是(0,0)。在孤岛上是“第一跳”,因为007可以在岛的任一地方起跳,所以要特殊考虑。

  4. 做深度优先遍历时,不需要像以前一样用for循环对图中的每一个结点进行遍历,只需要从孤岛这一个结点开始遍历就可以了。

  5. 另外,为了避免程序中出现“魔数”,最好把15,50这样的数在最开始用宏定义,程序的可读性和可移植性就变的更好了!

建议测试如下数据:

  5 13 -12 12 12 12 -12 -12 12 -12 50 50  

代码分析:

  头文件声明:1-7

  定义所用数据结构的名字及解释:8-14(注释中),24-28(全局变量的定义)

  定义“坐标”结构体:17-22(这里用double是方便计算距离,计算两点之间的距离时,要用sqrt开平方,计算结果是浮点数)

  计算“距离”的函数:30-44(第一跳要特殊计算)

  判断是否安全的函数:46-66(第一跳要特殊计算)

  深度优先遍历:66-95(具体已经写到程序的注释中)

  主函数,处理输入以及输出:97-130  

#include <iostream>
#include <vector>
#include <cmath>
#include <cstdlib>

#define FIRSTSTEP 15
#define BORDER 50
/*
* FIRSTSTEP 孤岛的半径,第一步能迈出多少米
* BORDER 边界范围[±BORDER/2, ±BORDER/2]
* vec 存储坐标信息 nNum 鳄鱼的数量 dis 007的跳跃距离
* visited 存储是否访问过信息
* firstStep/firstJudge 标记是否为第一次
*/
using namespace std;

struct pos
{
double x;
double y;
pos(double a, double b):x(a),y(b) {}
};

bool firstStep = true;
bool firstJudge = true;
int nNum, dis;
vector<pos> vec;
vector<bool> visited;

double Distance(pos p1, pos p2)
{
double xx = (p1.x - p2.x) * (p1.x - p2.x);
double yy = (p1.y - p2.y) * (p1.y - p2.y);
// 第一次是在中心,半径为15的岛上
if(firstStep == true)
{
return dis + FIRSTSTEP - sqrt(xx + yy);
firstStep = false;
}
else
{
return dis - sqrt(xx + yy);
}
}

bool judge(pos s)
{
if(firstJudge == true)
{
firstJudge = false;
if(fabs(s.x-BORDER)<=dis+FIRSTSTEP
||fabs(s.x+BORDER)<=dis+FIRSTSTEP
||fabs(s.y-BORDER)<=dis+FIRSTSTEP
||(s.y+BORDER)<=dis+FIRSTSTEP)
return true;
}
else
{
if(fabs(s.x-BORDER)<=dis
||fabs(s.x+BORDER)<=dis
||fabs(s.y-BORDER)<=dis
||(s.y+BORDER)<=dis)
return true;
}
return false;
}

bool DFS(int i)
{
// 标记当前结点已经被访问过了
visited[i] = true;
// 是否安全逃出
bool answer = false;
// 如果距离足够逃离,则逃离
if(judge(vec[i]) == true)
{
answer = true;
}
else
{
for(int j=0; j<vec.size(); j++)
{
// 如果没有被访问过,距离也够,那就继续做深度优先遍历
if(visited[j] == false && Distance(vec[i], vec[j]) >= 0)
{
firstStep = false;
answer = DFS(j);
if (answer == true)
break;
}
}
}
return answer;
}

int main()
{
cin >> nNum >> dis;
if(dis + FIRSTSTEP >= BORDER)
{
cout << "Yes" << endl;
return 0;
}
// 先把孤岛这个结点放进去
vec.push_back(pos(0, 0));
visited.push_back(false);
// 用邻接矩阵存储图
for(int i=0; i<nNum; i++)
{
double a, b;
cin >> a >> b;
vec.push_back(pos(a,b));
visited.push_back(false);
}
bool answer = false;
// 深度优先遍历,从数字最小的结点开始遍历
int i = 0;
if(!visited[i])
{
answer = DFS(i);
}

if (answer == true)
cout << "Yes" << endl;
else
cout << "No" << endl;

return 0;
}


AC成果:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐