这道题的解法就看想不想得到...
假设white与black横向距离大于纵向距离(否则交换),那么如果white与black要相遇,每次移动有八个方向,则最小步数和x=abs(black.x-white.x)-1;
很明显,每一步在y轴上至多扩展2个单位,即top+1,bottom-1,因此从white和black两边会夹出一个区间,这个区间就是white到black的最短路程上可能经过的点。
而white_black的区间则很好求,就是一个正方形的轮廓线,计算这个轮廓线和夹出的区间是否有交集就可以了。
因此我们分别计算white和black相遇前是否与white_black有交集即可。
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int INF = 1e9;
int n = 0;
struct node
{
int x, y;
void input() {scanf("%d%d", &x, &y);}
void swap() { int t = x;x = y;y = t;}
}w = {0, 0}, b = {0, 0}, w_b = {0, 0};
bool cross(int l1, int r1, int l2, int r2)
{
if(l1 > l2)
{
swap(l1, l2);
swap(r1, r2);
}
if(l2 <= r1) return true;
return false;
}
int calc(node ww, node bb)
{
int lw = ww.y, rw = ww.y, lb = 0, rb = 0;
int ll = 0, rr = 0, lwb = 0, rwb = 0;
int k = abs(bb.x-ww.x);
int p = ww.x<bb.x?1:-1;
for(int i = 1; i <= (k>>1)-1; ++i)
{
lw = max(1, lw-1);
rw = min(n, rw+1);
lb = max(1, bb.y-k+i);
rb = min(n, bb.y+k-i);
ll = max(lw, lb);
rr = min(rw, rb);
lwb = max(1, w_b.y-i);
rwb = min(n, w_b.y+i);
if((abs(ww.x+p*i-w_b.x) == i && cross(ll, rr, lwb, rwb)) || (abs(ww.x+p*i-w_b.x) < i && ((lwb <= rr && lwb >= ll) || (rwb <= rr && rwb >= ll))))
return i;
}
return INF;
}
int main()
{
scanf("%d", &n);
w.input();b.input();w_b.input();
if(abs(w.x-b.x) < abs(w.y-b.y))
w.swap(),b.swap(),w_b.swap();
int ans = min(calc(w, b), calc(b, w));
if(ans == INF)
{
puts("NO");
printf("%d", abs(w.x-b.x)-1);
}
else
{
puts("YES");
printf("%d", ans);
}
return 0;
}