传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1193
其实这个A*本质上还是远的时候贪心,近的时候bfs,估价函数是当前步数*3+曼哈短距离,每次跳的倍数与当前距离有关,
一开始写完拿数据一测90,第6个点死活过不去,然后就是喜闻乐见的对着数据调参数
Code:
#include<bits/stdc++.h> using namespace std; struct pos{ int x,y,step; bool operator==(const pos &X)const{ return x==X.x&&y==X.y; } pos(int _x=0,int _y=0,int _step=0): x(_x),y(_y),step(_step){} }s,t; int len(pos A,pos B){ return abs(A.x-B.x)+abs(A.y-B.y); } bool operator<(const pos &A,const pos &B){ int l1=len(A,t),l2=len(B,t); return l1+A.step*3>l2+B.step*3; } priority_queue<pos> q; const int dx[12]={1,1,-1,-1,2,2,-2,-2,0,0,4,-4}; const int dy[12]={2,-2,2,-2,1,-1,1,-1,4,-4,0,0}; const int sx[12]={1,1,1,1,1,1,1,1,2,2,2,2}; map<pair<int,int>,int>M; int main(){ int cnt=0; int ans=INT_MAX; cin>>s.x>>s.y>>t.x>>t.y; q.push(s);M[make_pair(s.x,s.y)]=0; while(!q.empty()){ pos u=q.top();q.pop(); if(u==t){ ans=min(ans,u.step); cnt++; if(cnt>2){ cout<<ans<<endl; return 0; } } int l=len(u,t); int up=l/6;up+=up==0; for(int i=0;i<12;i++){ int x=u.x+dx[i]*up,y=u.y+dy[i]*up,c=u.step+up*sx[i]; if(M.count(make_pair(x,y))&&M[make_pair(x,y)]>=c)continue; if(up==1)q.push(pos(x,y,c)); else{ if(len(pos(x,y,c),t)<len(u,t)) q.push(pos(x,y,c)); } M[make_pair(x,y)]=c; } }cout<<ans<<endl; return 0; }