数据结构PTA习题:06-图2 Saving James Bond - Easy Version (25分)

06-图2 Saving James Bond - Easy Version (25分)

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.
在老电影“007之生死关头”(Live and Let Die)中有一个情节,007被毒贩抓到一个鳄鱼池中心的小岛上,他用了一种极为大胆的方法逃脱 —— 直接踩着池子里一系列鳄鱼的大脑袋跳上岸去!(据说当年替身演员被最后一条鳄鱼咬住了脚,幸好穿的是特别加厚的靴子才逃过一劫。)
设鳄鱼池是长宽为100米的方形,中心坐标为 (0, 0),且东北角坐标为 (50, 50)。池心岛是以 (0, 0) 为圆心、直径15米的圆。给定池中分布的鳄鱼的坐标、以及007一次能跳跃的最大距离,你需要告诉他是否有可能逃出生天。

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.
首先第一行给出两个正整数:鳄鱼数量 N(≤100)和007一次能跳跃的最大距离 D。随后 N 行,每行给出一条鳄鱼的 (x,y) 坐标。注意:不会有两条鳄鱼待在同一个点上。

Output Specification:
For each test case, print in a line “Yes” if James can escape, or “No” if not.
如果007有可能逃脱,就在一行中输出"Yes",否则输出"No"。

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

我用的是邻接表存储图,深度优先搜索遍历图。
C语言实现:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
struct vertex
{
	int x;
	int y;
};
typedef struct vertex * Vertex;
struct edgenode
{
	int edgei;
	struct edgenode * Next;
};
typedef struct edgenode * Edge;
struct gnode
{
	Vertex data;
	Edge firstedge;
};
struct graph//邻接表存储图
{
	int Nv;
	int Ne;
	struct gnode * Gnode;
};
typedef struct graph * Graph;
Graph Creategraph(int N);
double distance(int x1, int y1, int x2, int y2);//计算两点之间的距离
void DFS(Graph G, int i, int D);//深度优先搜索
int * Visited;
int yes = 0;//yes==1表示可以上岸,yes==0表示不能上岸
int main()
{
	int i;
	int N, D;
	scanf("%d %d", &N, &D);
	Visited = (int *)malloc(N * sizeof(int));
	for (i = 0; i < N; i++)
	{
		Visited[i] = 0;
	}
	Graph G;
	G = Creategraph(N);
	for (i = 0; i < N; i++)
	{
		scanf("%d %d", &G->Gnode[i].data->x, &G->Gnode[i].data->y);
	}
	double d;
	int j;
	for (i = 0; i < N; i++)
	{
		for (j = 0; j < N; j++)
		{
			d = distance(G->Gnode[i].data->x, G->Gnode[i].data->y, G->Gnode[j].data->x, G->Gnode[j].data->y);
			if (d > 0 && d <= D)//将所有能从G->Gnode[i]跳到的结点都连接成链表
			{
				Edge Newnode;
				Newnode = (Edge)malloc(sizeof(struct edgenode));
				Newnode->edgei = j;
				Newnode->Next = G->Gnode[i].firstedge;
				G->Gnode[i].firstedge = Newnode;
			}
		}
	}
	//图的遍历
	Edge p;
	for (i = 0; i < N; i++)
	{
		if (distance(G->Gnode[i].data->x, G->Gnode[i].data->y, 0, 0) > D + 15) { continue; }//寻找能从小岛跳到的出发点
		if (Visited[i] == 0)
		{
			DFS(G, i, D);
			if (yes == 1) { break; }
		}
	}
	if (yes == 0) { printf("No"); }
	else { printf("Yes"); }
	return 0;
}
Graph Creategraph(int N)
{
	Graph G;
	G = (Graph)malloc(sizeof(struct graph));
	G->Nv = N;
	G->Gnode = (struct gnode *)malloc(N * sizeof(struct gnode));
	G->Ne = 0;
	int i;
	for (i = 0; i < N; i++)
	{
		G->Gnode[i].firstedge = NULL;
		G->Gnode[i].data = (Vertex)malloc(sizeof(struct vertex));
	}
	return G;
}
double distance(int x1, int y1, int x2, int y2)
{
	double d;
	d = sqrt((x1 - x2)*(x1 - x2) + (y1 - y2) * (y1 - y2));
	return d;
}
void DFS(Graph G, int i, int D)//深度优先搜索
{
	Visited[i] = 1;
	if (G->Gnode[i].data->x + D >= 50 || G->Gnode[i].data->x - D <= -50 || G->Gnode[i].data->y + D >= 50 || G->Gnode[i].data->y - D <= -50)//可以从出发点直接上岸
	{
		yes = 1;
	}
	else
	{
		Edge p;
		p = G->Gnode[i].firstedge;
		while (p != NULL)
		{
			if (Visited[p->edgei] == 0)
			{
				Visited[p->edgei] = 1;
				if (G->Gnode[p->edgei].data->x + D >= 50 || G->Gnode[p->edgei].data->x - D <= -50 || G->Gnode[p->edgei].data->y + D >= 50 || G->Gnode[p->edgei].data->y - D <= -50)//中间某点可以上岸
				{
					yes = 1;
				}
				else
				{
					DFS(G, p->edgei, D);
				}
			}
			p = p->Next;
		}
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值