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

//不用单独定义节点,而是用二维数组代替。 二维数组的内部是一维数组,x坐标,y坐标,flag是否被访问过 
//3个向量数组,first(n+1),path(n+1,-1),dist(n+1),path初始化为-1,表示未访问过
//path要定义为全局使用 
#include<iostream>    
#include<cmath> //abs和pow
#include<algorithm> //sqrt
#include<vector>
#include<queue>
#define MAXSIZE 101  
const double  R=7.5; 
using namespace std;  
  
//以下三项是全局变量,免得BFS每次都重新传入
double vertex[MAXSIZE][3];
int n, v;//v是pop出来的   
double m; 
bool flag=false;
vector<int> path(n+1,-1); 

bool cmp(int i,int j){
	return pow(vertex[i][0],2)+pow(vertex[i][1],2) < pow(vertex[j][0],2)+pow(vertex[j][1],2);
}

      
bool BFS(){    
	queue<int> q; 
	vector<int> first(n+1); 
	int i,fir,firstdist;	
	//1、对第一跳的处理 	
	for(int i=0;i<=n;i++) first[i]=i;
	sort(first.begin(),first.end(),cmp);
	/*for(int i=0;i<=n;i++){
		cout<<first[i]<<" ";
	}
	cout<<endl;
	return 1; */		
	for(int i=1;i<=n;i++){
		fir=first[i];
		firstdist=sqrt( pow(vertex[fir][0],2)+pow(vertex[fir][1],2)  );
		if( firstdist>R && firstdist<=R+m ){ //能跳出中心圆盘,但又不会跳上岸 
			q.push(fir); 
			path[fir]=0;
	   		vertex[fir][2]=1;//表示访问过 
			
		}
	} 	
   	//2、循环出队-进队 
   	while(!q.empty()){
   	   v=q.front();
	   q.pop();	
	   
	   if((fabs(vertex[v][0]) + m >= 50 || fabs(vertex[v][1]) + m >= 50)){//每次跳跃前判断是否能直接上岸  abs和fabs??? 
	   		//cout<<"v="<<v<<endl;
	   		flag=true; 
	   		break; 
	   }else{
	   	   for(int i=1;i<=n;i++){
	   		  if( vertex[i][2]==0 && pow(vertex[v][0]-vertex[i][0],2)+pow(vertex[v][1]-vertex[i][1],2)<=pow(m,2) ){
	   		  	 q.push(i); 
	   		  	 path[i]=v;
	   		  	 //cout<<"path["<<i<<"]="<<v<<" "; 
	   		  	 vertex[i][2]=1;//表示访问过 
	   		  }
	   	   }	   	
	   }  	   
	}
	return flag;
} 
           
  
int main(){    
    //freopen("input.txt","r",stdin);  
    cin>>n>>m;    
      
    vertex[0][0]=0; 
	vertex[0][1]=0;
	vertex[0][2]=0;
    for(int i=1;i<=n;i++){ 1~n,0为原点 
		cin>>vertex[i][0]>>vertex[i][1];  
		vertex[i][2]=0;
	}
	
    
    if(R+m>=50) flag=true;//直接从岛跨上岸 
    else flag=BFS();
    if(!flag) cout<<"0"<<endl;
	else{
		vector<int> dist;
		while(v){
			//cout<<"v="<<v<<" ";
			dist.push_back(v);
			v=path[v];
		}
		cout<<dist.size()+1<<endl;//最后一步直接跳上岸 
		for(int i=dist.size()-1;i>=0;i--){ //注意:dist.size()-1而不是dist.size() 
			cout<<vertex[dist[i]][0]<<" "<<vertex[dist[i]][1]<<endl;
		} 
	}             
    return 0;    
}   







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值