C BFS+无权最短路径记录 07-图5 Saving James Bond - Hard Version (30分)

07-图5 Saving James Bond - Hard Version (30分)

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 a shortest path to reach one of the banks. The length of a path is the number of jumps that James has to make.

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, if James can escape, output in one line the minimum number of jumps he must make. Then starting from the next line, output the position (x,y) of each crocodile on the path, each pair in one line, from the island to the bank. If it is impossible for James to escape that way, simply give him 0 as the number of jumps. If there are many shortest paths, just output the one with the minimum first jump, which is guaranteed to be unique.

Sample Input 1:

17 15
10 -21
10 21
-40 10
30 -50
20 40
35 10
0 -10
-25 22
40 -40
-30 30
-10 22
0 11
25 21
25 10
10 10
10 35
-30 10

Sample Output 1:

4
0 11
10 21
10 35

Sample Input 2:

4 13
-12 12
12 12
-12 -12
12 -12

Sample Output 2:

0

注意点
题目都会有让答案唯一的条件;
本题条件为当有多个最短路径时,输出第一跳最短的路径;
这里采取的方法是最小的先入队即可;

解题
头文件较多;
保存路径用到了stack;
BFS用到了queue;
排序用到了algorithm;
计算绝对值用到了cmath;

1.定义鳄鱼结构,存放每只鳄鱼的x,y坐标
#include<iostream>
#include<queue>
#include<stack>
#include<algorithm>
#define MAX 101
using namespace std;

struct Crocodile{
	int x;
	int y;
	//operator <(const Crocodile c)const{
		//return x*x+y*y<c.x*c.x+c.y*c.y;
	//}
}CR[MAX];

2.设定比较方法,用于sort
bool compare(Crocodile a,Crocodile b)
{
return a.x*a.x+a.y*a.y<b.x*b.x+b.y*b.y; //升序排列,如果改为return a>b,则为降序

}
3.input函数,用于输入数据
因为N和D在后面的BFS函数中要用,故设为全局变量
int N,D;
void input()
{
	cin>>N>>D;    //鳄鱼数量,每次跳跃的距离
	for(int i=0;i<N;i++)
		cin>>CR[i].x>>CR[i].y;	//读入每个鳄鱼的xy 
	sort(CR,CR+N,compare);
}
4.bfs函数
dist记录每一个鳄鱼的距离;
path记录路径;
先判断能否从岛上直接到岸上,能则一步,不能则继续;
将岛上能达到的鳄鱼先入队,入队顺序为鳄鱼的距离由小到大,
排序就是为此;	
进行BFS,当能跳到岸上时,就为最短路径,按要求输出即可;
保存在path中给的路径要放入stack中,然后挨个pop输出;
void BFS()    //输入第一个鳄鱼的序号 
{	
	int dist[MAX]; //记录距离 
	int path[MAX];//记录路径
	for(int i=0;i<N;i++) {       //不初始化的化只有第一个数为1; 
		dist[i]=-1;
		path[i]=-1;
	}
	queue<int> T;
	    //visited改为记录步数的dist 
	//岸上能跳到的先入队,且标记步数为1 
	for(int i=0;i<N;i++)
	if((D+7.5)*(D+7.5)>=(CR[i].x*CR[i].x+CR[i].y*CR[i].y)) 
	{
        if(50-abs(D+7.5)<=D||50-abs(D+7.5)<=D)
			{
				cout<<"1"<<endl;
				return;	 //一步跳到岸 
			}
		
		T.push(i);
		dist[i]=1;
	}
	
	while(!T.empty())        //队列不空 
	{
		int F=T.front();
		T.pop();
		int x=CR[F].x;
		int y=CR[F].y;
		
	//判断能否上岸	
		if(50-abs(x)<=D||50-abs(y)<=D) //可以上岸
		{
			cout<<dist[F]+1<<endl; //加上上岸的一步 
			stack<Crocodile> S;
			while(path[F]!=-1)
			{
				S.push(CR[F]);
				F=path[F];
			}
			S.push(CR[F]);
			while(!S.empty())
			{
				Crocodile a=S.top();
				S.pop();
				cout<<a.x<<" "<<a.y<<endl;
			}
			return; 
		 } 
		for(int i=0;i<N;i++)
		{
			//可以达到的坐标
			int X= CR[i].x;
			int Y= CR[i].y;
			if(((X-x)*(X-x)+(Y-y)*(Y-y))<=D*D&&dist[i]==-1)  //可以达到的鳄鱼,且没有走过 
			{
				T.push(i);
				dist[i]=dist[F]+1;
				path[i]=F;	
			} 
		}
	}
	cout<<"0"<<endl;
	return;
}

main函数

int main()
{
	input();
	BFS();
}

总结
无权最短路径
BFS解决:
需要dist【】记录每个点的距离;
path记录路径;
没必要用floyd(多源带权最短路径)
和dijkstra(单源最短路径),简单问题复杂化了。

发布了105 篇原创文章 · 获赞 6 · 访问量 4962

猜你喜欢

转载自blog.csdn.net/BLUEsang/article/details/105431406