bzoj 1193: [HNOI2006]马步距离

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值