干了一整天的活,农夫约翰完全忘记了他把拖拉机落在田地中央了。
他的奶牛非常调皮,决定对约翰来场恶作剧。
她们在田地的不同地方放了 捆干草,这样一来,约翰想要开走拖拉机就必须先移除一些干草捆。
拖拉机的位置以及 捆干草的位置都是二维平面上的整数坐标点。
拖拉机的初始位置上没有干草捆。
当约翰驾驶拖拉机时,他只能沿平行于坐标轴的方向(北,南,东和西)移动拖拉机,并且拖拉机必须每次移动整数距离。
例如,驾驶拖拉机先向北移动 2 单位长度,然后向东移动 3 单位长度。
拖拉机无法移动到干草捆占据的位置。
请帮助约翰确定他需要移除的干草捆的最小数量,以便他能够将拖拉机开到二维平面的原点。
输入格式
第一行包含三个整数: 以及拖拉机的初始位置 。
接下来 行,每行包含一个干草捆的位置坐标 。
输出格式
输出约翰需要移除的干草捆的最小数量。
数据范围
输入样例:
7 6 3
6 2
5 2
4 3
2 1
7 3
5 4
6 4
输出样例:
1
双端队列 + 广搜
- 将有草堆的点权设为,没有草堆的点权设为
- 注意此题搜索时可以出~的范围,所以设置为~即可
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;
}