菜鸡奋斗路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
作者: 陈越
单位: 浙江大学
时间限制: 400ms
内存限制: 64MB
代码长度限制: 16KB



个人分析:WOW!!拯救007,爽的一笔啊~~007现在被困在一个100X100大的池塘中央(0,0)直径为15的圆形小岛上,在这个池塘里有一些鳄鱼露着脑袋,现在我们要通过遍历所有的鳄鱼头(也就是结点)判断007是否能借助鳄鱼头跳到岸边!!这也太酷了吧!!

  emmmmmmmm,,,,,由于只需要判断007是不是能到岸边,而不要求得到最短路径,所以菜鸡采用了DFS(深度优先搜索)。只要在遍历结点的过程中,每到一个结点都判断该结点是否满足条件(007的跳跃距离>=结点到岸距离),如果满足,直接退出遍历,输出Yes即可。

进一步考虑,如果说,所有鳄鱼头(结点)构成一张无向图,那么007第一跳能够到的几个鳄鱼头应当特殊考虑,因为这几个结点可能代表了无向图中的几个连通集,从这几个结点出发使用DFS才能完成遍历。

代码如下:

#include<stdio.h>
#include<stdlib.h>
#define Maxsize 100
typedef struct GNode *Graph;
struct GNode{
	int x[Maxsize];
	int y[Maxsize];
	int size;
	int jump;
};
int Visit[Maxsize]={0};
bool IsSafe(Graph G,int n)
{
	if((G->jump-50)>=G->x[n]||G->x[n]>=(50-G->jump))
		return true;
	else if((G->jump-50)>=G->y[n]||G->y[n]>=(50-G->jump))
		return true;
	else
		return false;
}
bool Jump(Graph G,int n,int k)
{
	int Xdistance=G->x[n]-G->x[k];
	int Ydistance=G->y[n]-G->y[k];
	int Distance=Xdistance*Xdistance+Ydistance*Ydistance;
	if(Distance<=G->jump*G->jump)
		return true;
	else
		return false;
}
bool FirstJump(Graph G,int n)
{	
	int Xdistance=G->x[n];
	int Ydistance=G->y[n];
	int Distance=Xdistance*Xdistance+Ydistance*Ydistance;
	if(Distance<=(G->jump+7.5)*(G->jump+7.5))
		return true;
	else
		return false;
}
int DFS(Graph G,int n)
{
	Visit[n]=1;int flag=0;int k;
	if(IsSafe(G,n))          //每到一个结点都判断一下,当下是否能直接跳到岸
		flag=1;
	else
	{
		for(k=0;k<G->size;k++)
		{
			if(!Visit[k]&&Jump(G,n,k))
			{
				flag=DFS(G,k);
				if(flag==1) break;
			}
		}
	}
	return flag;	
}
void Save007(Graph G)
{
	int i,j;int flag=0;                //记录是否能安全到岸,若flag==0不能,flag==1能
	for(i=0;i<G->size;i++)
	{	
		if(!Visit[i]&&FirstJump(G,i))   //每个连通集的头结点(第一个鳄鱼头)开始一次DFS
		{                  
			flag=DFS(G,i);               
			if(flag==1) break;
		}
	}
	if(flag==1)
		printf("Yes\n");
	else
		printf("No\n");
}
int main()
{	//以x[]y[]存储所有鳄鱼的位置
	int number,jumpdistance,i;
	scanf("%d %d",&number,&jumpdistance);	
	getchar();
	Graph G;
	G=(Graph)malloc(sizeof(GNode));
	G->size=number;
	G->jump=jumpdistance;
	for(i=0;i<number;i++)
		scanf("%d %d",&G->x[i],&G->y[i]);
	//拯救007
	Save007(G); 
	return 0;
} 

测试结果:


总结:DFS和BFS真好玩!!!只要在遍历结点的图中加上判断条件,就能实现很多有趣的功能!!图真好玩!!CS真好玩!!教练,我要学CS!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值