干了一整天的活,农夫约翰完全忘记了他把拖拉机落在田地中央了。
他的奶牛非常调皮,决定对约翰来场恶作剧。
她们在田地的不同地方放了 NN 捆干草,这样一来,约翰想要开走拖拉机就必须先移除一些干草捆。
拖拉机的位置以及 NN 捆干草的位置都是二维平面上的整数坐标点。
拖拉机的初始位置上没有干草捆。
当约翰驾驶拖拉机时,他只能沿平行于坐标轴的方向(北,南,东和西)移动拖拉机,并且拖拉机必须每次移动整数距离。
例如,驾驶拖拉机先向北移动 22 单位长度,然后向东移动 33 单位长度。
拖拉机无法移动到干草捆占据的位置。
请帮助约翰确定他需要移除的干草捆的最小数量,以便他能够将拖拉机开到二维平面的原点。

输入格式

第一行包含三个整数:NN 以及拖拉机的初始位置 (x,y)(x,y)。
接下来 NN 行,每行包含一个干草捆的位置坐标 (x,y)(x,y)。

输出格式

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

数据范围

1≤N≤500001≤N≤50000,
1≤x,y≤10001≤x,y≤1000

输入样例:

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

输出样例:

1

image.png


  1. //能走出界
  2. #include <iostream>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <queue>
  6. #define x first
  7. #define y second
  8. using namespace std;
  9. typedef pair<int,int> PII;
  10. const int N = 1010;
  11. int dist[N][N];
  12. bool st[N][N],g[N][N]; //st判重,g记录干草
  13. int dx[4] = {-1,0,1,0}, dy[4] = {0,1,0,-1};
  14. int bfs(int sx, int sy) {
  15. deque<PII> q;
  16. q.push_front({sx,sy});
  17. memset(dist,0x3f,sizeof dist);
  18. dist[sx][sy] = 0;
  19. while (q.size()) {
  20. auto t = q.front();
  21. q.pop_front();
  22. //判重
  23. if (st[t.x][t.y]) continue;
  24. st[t.x][t.y] = true;
  25. //剪枝
  26. if (!t.x && !t.y) break;
  27. for (int i = 0; i < 4; ++i) {
  28. int a = t.x + dx[i], b = t.y + dy[i];
  29. if (a >= 0 && a < N && b >= 0 && b < N) {
  30. int w = 0;
  31. if (g[a][b]) w = 1;
  32. if (dist[a][b] > dist[t.x][t.y] + w) {
  33. dist[a][b] = dist[t.x][t.y] + w;
  34. //加入队列
  35. if (!w) q.push_front({a,b});
  36. else q.push_back({a,b});
  37. }
  38. }
  39. }
  40. }
  41. return dist[0][0];
  42. }
  43. int main() {
  44. int n,sx,sy;
  45. scanf("%d%d%d",&n,&sx,&sy);
  46. while (n -- ) {
  47. int x,y;
  48. scanf("%d%d",&x,&y);
  49. g[x][y] = true;
  50. }
  51. cout << bfs(sx,sy) << endl;
  52. return 0;
  53. }