题目描述
国际象棋和中国象棋中,马的移动规则相同,都是走“日”字,我们将这种移动方式称为马步移动。如右图所示,从标号为 0 0 0 的点出发,可以经过一步马步移动达到标号为 1 1 1 的点,经过两步马步移动达到标号为 2 2 2 的点。
任给平面上的两点 p p p 和 s s s,它们的坐标分别为 ( x p , y p ) (x_p, y_p) (xp,yp) 和 ( x q , y q ) (x_q, y_q) (xq,yq),其中 x p , y p , x q , y q x_p, y_p, x_q, y_q xp,yp,xq,yq 均为整数。从 ( x p , y p ) (x_p, y_p) (xp,yp) 出发经过一步马步移动可以达到 ( x p + 1 , y p + 2 ) , ( x p + 2 , y p + 1 ) , ( x p + 1 , y p − 2 ) , ( x p + 2 , y p − 1 ) , ( x p − 1 , y p + 2 ) , ( x p − 2 , y p + 1 ) , ( x p − 1 , y p − 2 ) , ( x p − 2 , y p − 1 ) (x_p + 1, y_p + 2), (x_p + 2, y_p + 1), (x_p + 1, y_p - 2), (x_p + 2, y_p - 1), (x_p - 1, y_p + 2), (x_p - 2, y_p + 1), (x_p - 1, y_p - 2), (x_p - 2, y_p - 1) (xp+1,yp+2),(xp+2,yp+1),(xp+1,yp−2),(xp+2,yp−1),(xp−1,yp+2),(xp−2,yp+1),(xp−1,yp−2),(xp−2,yp−1)。假设棋盘充分大,并且坐标可以为负数。现在请你求出从点 p p p 到点 s s s 至少需要经过多少次马步移动。

输入格式
一行包括 4 4 4 个整数 x p , y p , s p , s q x_p, y_p, s_p, s_q xp,yp,sp,sq。
输出格式
含一个整数,表示从点 p p p 到点 s s s 至少需要经过的马步移动次数。
样例
样例输入1:
1 2 7 9
样例输出1:
5
数据范围
对于  
     
      
       
       
         40 
        
       
         % 
        
       
      
        40\% 
       
      
    40% 的数据: 
     
      
       
        
        
          x 
         
        
          p 
         
        
       
         , 
        
        
        
          y 
         
        
          p 
         
        
       
         , 
        
        
        
          x 
         
        
          s 
         
        
       
         , 
        
        
        
          y 
         
        
          s 
         
        
       
      
        x_p,y_p,x_s,y_s 
       
      
    xp,yp,xs,ys 的绝对值都小于  
     
      
       
       
         100 
        
       
      
        100 
       
      
    100 。
 对于  
     
      
       
       
         60 
        
       
         % 
        
       
      
        60\% 
       
      
    60% 的数据: 
     
      
       
        
        
          x 
         
        
          p 
         
        
       
         , 
        
        
        
          y 
         
        
          p 
         
        
       
         , 
        
        
        
          x 
         
        
          s 
         
        
       
         , 
        
        
        
          y 
         
        
          s 
         
        
       
      
        x_p,y_p,x_s,y_s 
       
      
    xp,yp,xs,ys 的绝对值都小于  
     
      
       
       
         1 
        
        
        
          0 
         
        
          6 
         
        
       
      
        10^6 
       
      
    106 。
 对于  
     
      
       
       
         100 
        
       
         % 
        
       
      
        100\% 
       
      
    100% 的数据: 
     
      
       
        
        
          x 
         
        
          p 
         
        
       
         , 
        
        
        
          y 
         
        
          p 
         
        
       
         , 
        
        
        
          x 
         
        
          s 
         
        
       
         , 
        
        
        
          y 
         
        
          s 
         
        
       
      
        x_p,y_p,x_s,y_s 
       
      
    xp,yp,xs,ys 的绝对值都小于  
     
      
       
       
         1 
        
        
        
          0 
         
        
          7 
         
        
       
      
        10^7 
       
      
    107 。
题解
对于 40 % 40\% 40% 的数据,可以直接搜索(即普通的马走日)。
#include<bits/stdc++.h>
using namespace std;
int x, y, n, m;
int p, q;
struct node{
	int u, v, step;//x, y, 步数
};
queue<node> qr;
int dx[8] = {1, -1, 2, -2, 1, -1, 2, -2};
int dy[8] = {2, -2, 1, -1, -2, 2, -1, 1};
map<pair<int, int>, int> fl;
int ans = 0;
int main(){
//	p 是 x 的差,q 是 y 的差
	p = abs(n - x);
	q = abs(m - y);
	qr.push(node{0, 0, 0});
	while(!qr.empty()){
		node t = qr.front();
//		printf("%d %d %d\n", t.u, t.v, t.step);
		if(t.u == p && t.v == q){//搜到了
			printf("%d", t.step + ans); 
			return 0;
		}
		fl[make_pair(t.u, t.v)] = 1;
		qr.pop();
		for(int i = 0; i < 8; ++ i){
			int tx = t.u + dx[i];
			int ty = t.v + dy[i];
			if (tx, ty) 没有走过且再范围内
				qr.push({tx, ty, t.step + 1});
		}
	}
对于 100 % 100\% 100% 的数据,考虑将搜索的范围减小。
设  
     
      
       
       
         x 
        
       
      
        x 
       
      
    x 为  
     
      
       
       
         ∣ 
        
        
        
          x 
         
        
          p 
         
        
       
         − 
        
        
        
          s 
         
        
          p 
         
        
       
         ∣ 
        
       
      
        |x_p - s_p| 
       
      
    ∣xp−sp∣, 
     
      
       
       
         y 
        
       
      
        y 
       
      
    y 为  
     
      
       
       
         ∣ 
        
        
        
          y 
         
        
          p 
         
        
       
         − 
        
        
        
          s 
         
        
          p 
         
        
       
         ∣ 
        
       
      
        |y_p - s_p| 
       
      
    ∣yp−sp∣。始终让  
     
      
       
       
         x 
        
       
         ≥ 
        
       
         y 
        
       
      
        x \ge y 
       
      
    x≥y。
 对于  
     
      
       
       
         x 
        
       
      
        x 
       
      
    x 和  
     
      
       
       
         y 
        
       
      
        y 
       
      
    y 大于限定值(不要小于  
     
      
       
       
         8 
        
       
      
        8 
       
      
    8)的情况, 
     
      
       
       
         x 
        
       
      
        x 
       
      
    x 先减少  
     
      
       
       
         4 
        
       
      
        4 
       
      
    4(即向该方向移动  
     
      
       
       
         2 
        
       
      
        2 
       
      
    2 步, 
     
      
       
       
         y 
        
       
      
        y 
       
      
    y 可以不变,由于有限定值的限制,所以不用判断)。如果  
     
      
       
       
         y 
        
       
      
        y 
       
      
    y 走到需要跳的时候(先不动  
     
      
       
       
         y 
        
       
      
        y 
       
      
    y,需要时再动,移动  
     
      
       
       
         2 
        
       
      
        2 
       
      
    2 步, 
     
      
       
       
         y 
        
       
      
        y 
       
      
    y 可以减少  
     
      
       
       
         2 
        
       
      
        2 
       
      
    2), 
     
      
       
       
         y 
        
       
      
        y 
       
      
    y 减少  
     
      
       
       
         2 
        
       
      
        2 
       
      
    2。
接下来搜索就很简单了,建议使用广搜。
代码:
int x, y, n, m;
int p, q;
int ans = 0;
int main(){
	scanf("%d %d %d %d", &x, &y, &n, &m);
	p = abs(n - x);
	q = abs(m - y);
	while(p + q >= 20){
		if(p < q){//保持 p >= q
			swap(p, q);
		}
		p -= 4;
		if(p - 4 <= q * 2){
			q -= 2;
		}
		ans += 2;
	}
	bfs();//见上文,范围根据限定值来定,至少限定值加 4
	输出 ans + bfs 的值
} 



















