**可以想象任意一个最短步数形成的路径任意交换两个选择的向量形成的路径是不一样的,那么一定能找到在路径中离
l:(sx,sy)-> (tx,ty)直线最近的路径,所以只要找到这个路径即可,可以将所有背离起点终点和离 l 距离超过最大向量的点不入队,这样搜到
的点的个数极限就是(5000 + 5000)* sqrt(2)* 10 * 2 * sqrt(2) = 400000,然后写个hash记录即可:**
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <queue>
#define sqr(x) ((x)*(x))
using namespace std;
typedef long long LL;
const int prime = 999997;
const int maxn = 17;
const int maxm = 400007;
int kase, fx, fy, tx, ty, n, idx;
int speed[17][2], head[prime], Maxs;
int a, b, c;
struct Node1{
int x, y, step;
Node1(){}
Node1(int x, int y, int step) : x(x),y(y),step(step) {}
};
struct Node2{
int x, y, Next;
}edge[maxm];
int Hash(int x, int y) {
return (((x<<15)^y)%prime+prime)%prime;
}
bool addedge(int key, int x, int y) {
for(int i = head[key]; i != -1; i = edge[i].Next) {
if(edge[i].x == x && edge[i].y == y) return false;
}
edge[idx].x = x;
edge[idx].y = y;
edge[idx].Next = head[key];
head[key] = idx++;
return true;
}
bool isValid(int x, int y) {
if(sqr(x-fx)+sqr(y-fy) <= Maxs) return true; //起点画圆
if(sqr(x-tx)+sqr(y-ty) <= Maxs) return true; //终点画圆
if((tx-fx)*(x-fx)+(ty-fy)*(y-fy) < 0) return false; //逆起点方向
if((fx-tx)*(x-tx)+(fy-ty)*(y-ty) < 0) return false; //逆终点方向
if(sqr((LL)a*x+b*y+c) <= (LL)Maxs*(sqr(a)+sqr(b)))return true; //点到对角线距离小于Maxs
return false;
}
void bfs() {
queue<Node1> Q;
Node1 tmp(fx,fy,0);
Q.push(tmp);
addedge(Hash(fx,fy),fx,fy);
while(!Q.empty()) {
Node1 cur = Q.front(); Q.pop();
if(cur.x == tx && cur.y == ty) {
printf("%d\n", cur.step);
return ;
}
for(int i = 0; i < n; ++i) {
int xx = cur.x + speed[i][0];
int yy = cur.y + speed[i][1];
if(isValid(xx, yy) && addedge(Hash(xx,yy),xx,yy)) {
tmp = Node1(xx, yy, cur.step+1);
Q.push(tmp);
}
}
}
printf("IMPOSSIBLE\n");
}
int main() {
scanf("%d", &kase);
while(kase--) {
idx = 0; Maxs = 0;
memset(head, -1, sizeof(head));
scanf("%d%d%d%d", &fx, &fy, &tx, &ty);
scanf("%d", &n);
for(int i = 0; i < n; ++i) {
scanf("%d%d", &speed[i][0], &speed[i][1]);
Maxs = max(Maxs, sqr(speed[i][0])+sqr(speed[i][1]));
}
a = ty-fy; b = fx-tx; c = fy*tx-fx*ty;
bfs();
}
}