浙大《数据结构》06-图2 Saving James Bond - Easy Version

This time let us consider the situation in the movie “Live and Let Die” in which James Bond, the world’s most famous spy, was captured by a group of drug dealers. He was sent to a small piece of land at the center of a lake filled with crocodiles. There he performed the most daring action to escape – he jumped onto the head of the nearest crocodile! Before the animal realized what was happening, James jumped again onto the next big head… Finally he reached the bank before the last crocodile could bite him (actually the stunt man was caught by the big mouth and barely escaped with his extra thick boot).

Assume that the lake is a 100 by 100 square one. Assume that the center of the lake is at (0,0) and the northeast corner at (50,50). The central island is a disk centered at (0,0) with the diameter of 15. A number of crocodiles are in the lake at various positions. Given the coordinates of each crocodile and the distance that James could jump, you must tell him whether or not he can escape.

Input Specification:

Each input file contains one test case. Each case starts with a line containing two positive integers N (≤100), the number of crocodiles, and D, the maximum distance that James could jump. Then N lines follow, each containing the (x,y) location of a crocodile. Note that no two crocodiles are staying at the same position.

Output Specification:

For each test case, print in a line “Yes” if James can escape, or “No” if not.

Sample Input 1:
14 20
25 -15
-25 28
8 49
29 15
-35 -2
5 28
27 -29
-8 -28
-20 -35
-25 -20
-13 29
-30 15
-35 40
12 12
Sample Output 1:
Yes
Sample Input 2:
4 13
-12 12
12 12
-12 -12
12 -12
Sample Output 2:
No

此题的思路就是转化为图的遍历问题。Bond的跳跃距离可以用来判断两个鳄鱼(结点)之间是否存在边,距离在跳跃范围内就存在边。从起始位置出发,遍历包含起始点在内的图的连通分量(如果有些孤立点,不需要继续进行遍历),如果遍历包含了可以到达岸边的点,就说明Bond可以成功逃出,否则失败。至于遍历用DFS还是BFS,我感觉好像都行?因为我的代码不会在访问到可以到达岸边的结点时就break,还是会访问完,所以哪种遍历应该都一样。
代码如下:

#include<iostream>
#include<cmath>
using namespace std;

int coord[101][2]; // 存储结点坐标
int vertexes[101] = { 0 };
int flag = 0;

int reachCoast(int x, int y, int D) { //判断一个点的坐标是否满足成功逃出
	int distance1 = abs(abs(x) - 50);
	int distance2 = abs(abs(y) - 50);
	if (distance1 <= D || distance2 <= D )
		return 1;
	else return 0;
}

int distance(int x1, int y1, int x2, int y2) { //返回距离的平方
	return pow(x1 - x2, 2) + pow(y1 - y2, 2);
}

void DFS(int ver, int N, int D) { //以vertex为起点进行深度优先搜索
	vertexes[ver] = 1; //该点设为已发现
	int d = D;
	if (ver == 0) d = d + 15 / 2;
	if (reachCoast(coord[ver][0], coord[ver][1], D))
		flag = 1;
	for (int i = 0; i < N+1; i++) {
		if ( distance(coord[ver][0], coord[ver][1], coord[i][0], coord[i][1]) <= pow(d, 2) && vertexes[i] == 0)
			DFS(i, N, D);
	}
}

int main() {
	int N = 0, D = 0; //N是结点个数(不包括起点), D是弹跳半径
	cin >> N >> D;
	coord[0][0] = 0;
	coord[0][1] = 0;
	for (int i = 1; i < N + 1; i++) {
		int x = 0, y = 0;
		cin >> x >> y;
		coord[i][0] = x;
		coord[i][1] = y;
	}
	//DFS遍历(0,0)所在的连通分量
	DFS(0, N, D);
	if (flag == 1) printf("Yes\n");
	else printf("No\n");
}

个人感觉这道题在距离的计算上比较宽松,全程用int,然后其实 > > >还是 > = >= >=好像也影响不大。因为我开始的时候2、3测试点没过,看别人说把 > = >= >=改为 > > >就过了,但是发现没用。最后通过也是用的 > > >
PS:我看到网上有些博客第一次跳跃是按照D+15算,但是The central island is a disk centered at (0,0) with the diameter of 15中的diameter不是直径吗?然后我用的是15/2,但是前面说的那个地方又用了<=,也通过了。。。所以我感觉有点玄学。
(如果感觉程序没问题(比如只有2,3测试点没过),建议试一下我刚说的这几个地方的排列组合,说不定能通过。)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值