1193: [HNOI2006]马步距离

Time Limit: 10 Sec  Memory Limit: 162 MB

Description

Input

只包含4个整数,它们彼此用空格隔开,分别为xp,yp,xs,ys。并且它们的都小于10000000。

Output

含一个整数,表示从点p到点s至少需要经过的马步移动次数。

Sample Input

1 2 7 9

Sample Output

5
 
看到这道题思绪很乱,感觉在数学上面找不到一个合适的解法。
于是我罪恶地找到了度娘……
其实思路跟我的比较接近。
先设p、s点的横坐标纵坐标距离分别为x、y,如果x<y就交换。然后如果x大于50,就进行以下操作:
      如果x-4>2*y就将其x-=4(相当于横跨两步),然后计数器(tot)加2
      否则x-=2;y--;tot++;相当于往终点走一步。然后要随时注意x、y取绝对值,x一定要大于y
      x<=50时跳出循环
最后爆搜==,代码轻松愉快。
然后Accept!
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
int a[3][3],n1,m1,b[60][60],ss=0;
int Abs(int x)
 {
    if (x<0) return -x;
    return x;
 }
int Max(int x,int y)
 {
    if (x<y) return y;else return x;
 }
void Bfs(int x,int y,int z)
 {
    if (x<0||x*y<0||x>50||y>50) return;
    if (b[x][y]==0||b[x][y]>z||z==0) b[x][y]=z;else
      return;
    Bfs(x+2,y+1,z+1);Bfs(x+2,y-1,z+1);Bfs(x+1,y+2,z+1);
    Bfs(x+1,y-2,z+1);Bfs(x-1,y+2,z+1);Bfs(x-1,y-2,z+1);
    Bfs(x-2,y+1,z+1);Bfs(x-2,y-1,z+1);
    return;
 }
int main()
 {
    int i,j,k,l,q,w,e,n2,m2;
    scanf("%d%d%d%d",&n1,&m1,&n2,&m2);
    memset(b,0,sizeof(b));
    n2=Abs(n2-n1);m2=Abs(m2-m1);
    m1=Max(n2,m2);n1=n2+m2-m1;
    a[0][0]=0;a[0][1]=3;a[1][0]=3;a[1][1]=2;a[1][2]=1;a[2][1]=1;
    a[0][2]=2;a[2][0]=2;a[2][2]=4;
    if (Max(n1,m1)<3)
     {
        printf("%d\n",a[n1][m1]);
        return 0;
     }
    while (m1>50)
     {
        ss++;
        if (m1-4>n1*2) 
         {
            m1-=4;
            ss++;
         }else
         {
            m1-=2;
            n1--;
         }
        n1=Abs(n1);m1=Abs(m1);
        if (n1>m1)
         {
            e=n1;n1=m1;m1=e;
         }
     }
    Bfs(n1,m1,0);
    printf("%d\n",b[0][0]+ss);
 }