题意:50*50的池塘里有n条鳄鱼,中心有直径为15的圆台,jams要踩着鳄鱼的头部连跳到池塘岸上,jams最大跨步为m,要求输出jams最小跳的步数,以及路径(被踩的鳄鱼坐标)
tip:sort+dfs+路径记录
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
struct position {
int x,y;
};
struct position f[103];
int checked[103]= {0};
int n,m;
bool judge(int x,int y) {
if(abs(x)+m>=50||abs(y)+m>=50)//判断是否可一步到边界
return true;
return false;
}
vector<int> ans,temp;
int minjump=1e7;
void dfs(int x,int y,int s,int jump) {
if(s!=-1) {//排除原点
temp.push_back(s);
checked[s]=1;
}
if(jump>=minjump)//剪枝,如果跳的步数比最小的还大则无需继续遍历
return;
if(judge(x,y)) {
if(jump<minjump) {//更新最小路径和最小跳数
ans=temp;
minjump=jump;
}
return ;
}
for(int i=0; i<n; ++i)
if(x==0&&y==0) {
if(!checked[i]&&sqrt((pow(f[i].x,2)+pow(f[i].y,2)))-7.5<=m) {//找到第一个可跳的鳄鱼
dfs(f[i].x,f[i].y,i,jump+1);
checked[i]=0;
temp.pop_back();
}
} else if(!checked[i]&&(pow(f[s].x-f[i].x,2)+pow(f[s].y-f[i].y,2))<=m*m) {//找到下一个可跳的鳄鱼
dfs(f[i].x,f[i].y,i,jump+1);
checked[i]=0;
temp.pop_back();
}
}
bool cmp(struct position a,struct position b) {
return a.x*a.x+a.y*a.y<b.x*b.x+b.y*b.y;//按照与中心的距离排序
}
int main() {
cin>>n>>m;
for(int i=0; i<n; ++i)
cin>>f[i].x>>f[i].y;
if(m>=42.5) {//一步能跳到
cout<<"1\n";
return 0;
}
sort(f,f+n,cmp);
dfs(0,0,-1,0);
if(minjump!=1e7) {
cout<<minjump+1<<endl;
for(int i=0; i<ans.size(); ++i)
cout<<f[ans[i]].x<<" "<<f[ans[i]].y<<endl;
} else cout<<"0\n";
return 0;
}