Description
Input
只包含4个整数,它们彼此用空格隔开,分别为xp,yp,xs,ys。并且它们的都小于10000000。
Output
含一个整数,表示从点p到点s至少需要经过的马步移动次数。
Sample Input
1 2 7 9
Sample Output
5
第一眼看上去就可以知道是贪心了。大概可以推测出肯定是先靠近目标点跳,然后在一定范围内跑bfs.这个一定范围我设置的是从目标点往外扩展5格(11*11)【其实本来设置的是5*5结果自己写的大概有点问题然后就改大了】
下面说说贪心,要求不断地向目标点跳.可马步是要同时改变行和列。所以我们不妨让行列中差距大的那个跳两格,小的那个跳一格.自己脑补下这么跳大概是没问题的【可以拿题目给的那幅图来观察】
代码一开始想一下跳好几步结果发现一次一步来贪心就可以了
#include<queue>
#include<cstdio>
using namespace std;
struct point
{
int x,y;
};
queue <point>Q;
int map[111][111];
int move[8][2]={{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};
inline int xabs(int x)
{
if(x<0)
x=-x;
return x;
}
inline int bfs(int x,int y,int xs,int ys)
{
while(!Q.empty())
Q.pop();
point nx;
nx.x=x;
nx.y=y;
Q.push(nx);
while(!Q.empty())
{
int xx=Q.front().x,yy=Q.front().y;
Q.pop();
if(xx==10&&yy==10)
return map[xx][yy];
int i;
for(i=0;i<=7;i++)
{
int xt=xx+move[i][0],yt=yy+move[i][1];
if(xt>=6&&xt<=14&&yt>=6&&yt<=14)
{
if(!map[xt][yt])
{
point nt;
nt.x=xt;
nt.y=yt;
map[xt][yt]=map[xx][yy]+1;
Q.push(nt);
}
}
}
}
}
int main()
{
int xp,yp,xs,ys;
scanf("%d%d%d%d",&xp,&yp,&xs,&ys);
int sum=0;
int i;
int dx=xp,dy=yp;
while(xabs(dx-xs)>4||xabs(dy-ys)>4)
{
xp=dx;
yp=dy;
if(xabs(dx-xs)>xabs(dy-ys)&&xabs(dx-xs)>2)
{
if(dx>xs)
dx-=2;
else
dx+=2;
if(dy>ys)
dy-=1;
else
dy+=1;
}
else
{
if(dx>xs)
dx-=1;
else
dx+=1;
if(dy>ys)
dy-=2;
else
dy+=2;
}
sum++;
}
if(sum>0)
sum--;
sum+=bfs(xp-xs+10,yp-ys+10,xs,ys);
printf("%d\n",sum);
return 0;
}