题意:给你一个图,给出n个石头的坐标,一个起点,一个终点。每次移动可以往东南西北四个方向移动,一旦移动就必须遇到石头才能停下来。问到达终点的最小步数。
思路:一看就是一道BFS的题目,但是由于坐标范围特别大,所以将坐标给离散化,然后在bfs中再用二分相应找到停留的石头位置。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
using namespace std;
#define N 20005
#define mp make_pair
struct R{
int x, y;
}ro[N];
struct P{
int x, y, t;
P(){}
P(int _x, int _y, int _t):x(_x), y(_y), t(_t){}
};
queue<P>Q;
map<pair<int,int>, bool>M;
int n, sx, sy, ex, ey, rx[N], ry[N], xn, yn;
vector<int>X[N], Y[N];
int find(int x, int y, int d, int &tx, int &ty) {
int f, r, mid, idx, i, j;
if (d < 2) {
idx = lower_bound(ry, ry+yn, y)-ry;
if (idx == yn || ry[idx] != y) return -1;
if (!d) {
if (Y[idx][0] > x) return -1;
}else {
if (Y[idx][Y[idx].size()-1] < x) return -1;
}
f = 0, r = Y[idx].size()-1;
while (f < r) {
mid = f+r>>1;
if (Y[idx][mid] < x) f = mid+1;
else r = mid;
}
if (!d) {
if (Y[idx][f] >= x) f--;
}
ty = y, tx = Y[idx][f]+(d?-1:1);
}else {
idx = lower_bound(rx, rx+xn, x)-rx;
if (idx == xn || rx[idx] != x) return -1;
d -= 2;
if (!d) {
if (X[idx][0] > y) return -1;
}else {
if (X[idx][X[idx].size()-1] < y) return -1;
}
f = 0, r = X[idx].size()-1;
while (f < r) {
mid = f+r>>1;
if (X[idx][mid] < y) f = mid+1;
else r = mid;
}
if (!d) {
if (X[idx][f] >= y) f--;
}
tx = x, ty = X[idx][f]+(d?-1:1);
}
return 0;
}
void bfs() {
while (!Q.empty()) Q.pop();
M.clear();
Q.push(P(sx, sy, 0));
M[mp(sx, sy)] = 1;
P tm;
int i, j, k, tx, ty;
while (!Q.empty()) {
tm = Q.front(), Q.pop();
if (tm.x == ex && tm.y == ey) {
printf("%d\n", tm.t);
return;
}
for (i = 0;i < 4;i++) {
j = find(tm.x, tm.y, i, tx, ty);
if (j == -1) continue;
if (M.find(mp(tx, ty)) != M.end()) continue;
M[mp(tx, ty)] = 1;
Q.push(P(tx, ty, tm.t+1));
}
}
}
int main() {
int i, j, k;
while (~scanf("%d", &n)) {
scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
for (i = 0;i < n;i++) {
scanf("%d%d", &ro[i].x, &ro[i].y);
rx[i] = ro[i].x, ry[i] = ro[i].y;
X[i].clear(), Y[i].clear();
}
sort(rx, rx+n), sort(ry, ry+n);
xn = unique(rx, rx+n)-rx, yn = unique(ry, ry+n)-ry;
for (i = 0;i < n;i++) {
j = lower_bound(rx, rx+xn, ro[i].x)-rx;
X[j].push_back(ro[i].y);
j = lower_bound(ry, ry+yn, ro[i].y)-ry;
Y[j].push_back(ro[i].x);
}
for (i = 0;i < xn;i++) sort(X[i].begin(), X[i].end());
for (i = 0;i < yn;i++) sort(Y[i].begin(), Y[i].end());
bfs();
}
}