问题描述
小U掌握了国际象棋中“象”和“马”的跳跃能力,在一个无限大的平面直角坐标系中,她每一步可以模仿象和马的跳跃方式移动。在每次询问中,小U需要计算从初始坐标 到 所需的最少步数。
- 象的跳跃:可以移动到 或 ,其中 是任意整数。
- 马的跳跃:可以移动到 ,其中 且 。
你需要在每次询问中计算从起点到终点所需的最少步数。
测试样例
样例1:
输入:
x1 = 0, y1 = 0, x2 = 1, y2 = 1输出:1
样例2:
输入:
x1 = 0, y1 = 0, x2 = 2, y2 = 1输出:1
样例3:
输入:
x1 = 0, y1 = 0, x2 = 3, y2 = 3输出:1
样例4:
输入:
x1 = -3, y1 = -2, x2 = 2, y2 = 1输出:2
解题思路
因为k大小没有限制,要保证最小步数应优先使用"象"进行移动。
初、末位置为矩形对角线或直线
设初位置为A,末位置为B;
d1、d2分别为俩正方形的边长;
由图可知"d1+d2=L","d1-d2=H",解得2d1=L+H;
分类讨论
情况一:若初始位置与最终位置连线恰为正方形对角线,则步数为1;
情况二:若L+H为偶数则d1有解,移动方式为两次"象",步数为2;
情况三:若L+H=3则可通过“马”一次到达,步数为1;
若L+H为奇数,我们可以以“马”的方式移动一次,“L变化2,H变化1”,或“L变化1,H变化2”,变化2不影响奇偶性,变化1改变奇偶性,所以L+H变为偶数;
情况四:若此时L=H则步数为2,“马”+“象”
情况五:若不等则步数为3,“马”+“象1”+“象2”
A,B成直线时结论仍然成立。
#include <iostream>
int solution(int x1, int y1, int x2, int y2) {
int dx = abs(x1 - x2), dy = abs(y1 - y2);//计算两点x,y轴距离
if (dx == dy) { //情况一
if (dx == 0)
return 0;
return 1;
}
if ((dx + dy) % 2 == 0) //情况二
return 2;
if (dx < dy) //保证dx为矩形的长,dy为宽
std::swap(dx, dy);
if (dx + dy == 3) //情况三
return 1;
if (dx - dy == 1 || dx - dy == 3) { //情况四,成矩形时,长宽相差为1或3,可通过“马”移动变为正方形
return 2;
}
return 3; //情况五
}
int main() {
std::cout << (solution(0, 0, 1, 1) == 1) << std::endl;
std::cout << (solution(0, 0, 2, 1) == 1) << std::endl;
std::cout << (solution(0, 0, 3, 3) == 1) << std::endl;
std::cout << (solution(-3, -2, 2, 1) == 2) << std::endl;
}