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

16 篇文章 0 订阅
1 篇文章 0 订阅

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.

假设湖是一个100乘100的正方形。 假设湖的中心在(0,0),东北角在(50,50)。 中央岛是直径为15,以(0,0)为中心的圆盘。许多鳄鱼在湖的不同位置。考虑到每个鳄鱼的坐标和詹姆斯可以跳跃的距离,你必须告诉他他是否可以逃脱。

Input Specification:

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

每个输入文件包含一个测试用例。 每个案例从一个包含两个正整数的行开始,鳄鱼的数量N(≤100)和詹姆斯可以跳跃的最大距离D。 接下来的N行,每个包含鳄鱼的(x,y)位置。 注意,没有两个鳄鱼停留在相同的位置。

Output Specification:

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

对于每个测试用例,如果James可以逃脱,则在行中输入“是”,否则输出“否”。


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

思路:

想法是很简单。这种情况适合DFS。因为小岛也有半径,因此第一跳要特殊处理。

实际代码写起来,还是对递归理解不深,代码总是写不好。以后要注意三个因素:

a)出口条件,即递归“什么时候结束”,这个通常在递归函数的开始就写好; 

b)如何由"情况 n" 变化到"情况 n+1", 也就是递推,也就是一般情况——"正在"递归中的情况;

c)当前case的工作,也就是这个递归调用以什么样的。

因此这次的DFS函数要注意:

a)出口条件:能够跳上岸,或者没有鳄鱼可跳,或者鳄鱼都跳过了但还是上不了岸;

b)递推:有可以跳上去的未标记过的鳄鱼;

c)当前case的工作:已经站在一条鳄鱼上,标记该鳄鱼已经跳过了。

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define MaxVertexNum 101    /* 最大顶点数设为101 */

int N,D;//鳄鱼数,跳跃距离 
struct Crocodile{		
    int x;
    int y;
}cro[MaxVertexNum];//存储鳄鱼坐标的数据结构
 	
bool Visited[MaxVertexNum]={false};
//判断当前鳄鱼是否访问过(全局变量或static变量在未初始化时为0,局部变量为分配的内存中遗留的数据)
 
bool result=false;		//存储结果,是否能逃脱 

double Distance(int i,int j)//计算两个鳄鱼的距离 
{
	double b;
	b=sqrt(pow(cro[i].x-cro[j].x,2)+pow(cro[i].y-cro[j].y,2));
	return b;
}

bool CanEscape(int i)//判断是否能从当前鳄鱼跳一次就否脱离 
{
	if((cro[i].x<=D-50)||(cro[i].y<=D-50)||(cro[i].x>=50-D)||(cro[i].y>=50-D))
	{
		return true;
	}else{
		return false;
	}
}

bool DFS(struct Crocodile cro[],int V,bool Visited[])//深度搜索 
{
	Visited[V]=true;//当前坐在的鳄鱼 
	if(CanEscape(V))//出口条件 
	{
		result=true;
	}else{			//递归部分 
		for(int i=1;i<=N;i++)
		{
			if((Visited[i]==false)&&(Distance(V,i)<=D))//当没有访问过且能跳过去 
			{
				result=DFS(cro,i,Visited);
			}
		}			
	}
	return result;			
}

int main()
{
	scanf("%d %d",&N,&D);
	
	cro[0].x=0;	//下标为0的结点为小岛 
	cro[0].y=0;
	for(int i=1;i<=N;i++)//输入鳄鱼坐标 
	{
		scanf("%d %d",&cro[i].x,&cro[i].y);
	}
	
	Visited[0]=true;
	for(int i=1;i<=N;i++)
	{

		if(Distance(0,i)<=(D+7.5))//从小岛跳到鳄鱼上 
		{
			result=DFS(cro,i,Visited);
			if(result)
			{
				printf("Yes");
				break;
			} 
		}
	}
	if(!result)
	{
		printf("No");
	}
	
	return 0;
}
 



  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值