干了一整天的活,农夫约翰完全忘记了他把拖拉机落在田地中央了。

他的奶牛非常调皮,决定对约翰来场恶作剧。

她们在田地的不同地方放了 拖拉机(寒假每日一题 4)_c++ 捆干草,这样一来,约翰想要开走拖拉机就必须先移除一些干草捆。

拖拉机的位置以及 拖拉机(寒假每日一题 4)_c++ 捆干草的位置都是二维平面上的整数坐标点。

拖拉机的初始位置上没有干草捆。

当约翰驾驶拖拉机时,他只能沿平行于坐标轴的方向(北,南,东和西)移动拖拉机,并且拖拉机必须每次移动整数距离。

例如,驾驶拖拉机先向北移动 2 单位长度,然后向东移动 3 单位长度。

拖拉机无法移动到干草捆占据的位置。

请帮助约翰确定他需要移除的干草捆的最小数量,以便他能够将拖拉机开到二维平面的原点。

输入格式
第一行包含三个整数:拖拉机(寒假每日一题 4)_c++ 以及拖拉机的初始位置 拖拉机(寒假每日一题 4)_广搜_04

接下来 拖拉机(寒假每日一题 4)_c++ 行,每行包含一个干草捆的位置坐标 拖拉机(寒假每日一题 4)_广搜_04

输出格式
输出约翰需要移除的干草捆的最小数量。

数据范围
拖拉机(寒假每日一题 4)_dijkstra_07
输入样例:

7 6 3
6 2
5 2
4 3
2 1
7 3
5 4
6 4

输出样例:

1

双端队列 + 广搜

  1. 将有草堆的点权设为拖拉机(寒假每日一题 4)_dijkstra_08,没有草堆的点权设为拖拉机(寒假每日一题 4)_c++_09
  2. 注意此题搜索时可以出拖拉机(寒假每日一题 4)_dijkstra_08~拖拉机(寒假每日一题 4)_#define_11的范围,所以设置为拖拉机(寒假每日一题 4)_广搜_12~拖拉机(寒假每日一题 4)_#include_13即可
#include<iostream>
#include<cstring>
#include<deque>

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;
const int N = 1010;

bool g[N][N], st[N][N];
int dist[N][N];

int bfs(int sx, int sy){

deque<PII> q;
q.push_back({sx, sy});
memset(dist, 0x3f, sizeof dist);
dist[sx][sy] = 0;

int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};

while(q.size()){

auto t = q.front();
q.pop_front();


if(st[t.x][t.y]) continue;
st[t.x][t.y] = true;

if(!t.x && !t.y) break; // 0,0

for(int i = 0; i < 4; i++){

int x = t.x + dx[i], y = t.y + dy[i];
if(x >= 0 && x < N && y >=0 && y < N){

int w = 0;
if(g[x][y]) w = 1;
if(dist[x][y] > dist[t.x][t.y] + w){

dist[x][y] = dist[t.x][t.y] + w;
if(!w) q.push_front({x, y});
else q.push_back({x, y});
}
}
}
}

return dist[0][0];
}

int main(){

int n, sx, sy;
scanf("%d%d%d", &n, &sx, &sy);
while(n--){

int x, y;
scanf("%d%d", &x, &y);
g[x][y] = true;
}

printf("%d\n", bfs(sx, sy));

return 0;
}