Day2-I-Knight's Problem POJ - 3985

You must have heard of the Knight's Tour problem. In that problem, a knight is placed on an empty chess board and you are to determine whether it can visit each square on the board exactly once. 

Let's consider a variation of the knight's tour problem. In this problem, a knight is place on an infinite plane and it's restricted to make certain moves. For example, it may be placed at (0, 0) and can make two kinds of moves: Denote its current place as (x,y), it can only move to (x+1,y+2) or (x+2,y+1). The goal of this problem is to make the knight reach a destination position as quickly as possible (i.e. make as less moves as possible).

Input

The first line contains an integer T ( T < 20) indicating the number of test cases. 
Each test case begins with a line containing four integer: fx fy tx ty(-5000<=fx,fy,tx,ty<=5000). The knight is originally placed at (fx, fy) and (tx, ty) is its destination. 

The following line contains an integer m(0 < m <= 10), indicating how many kinds of moves the knight can make. 

Each of the following m lines contains two integer mx my(-10<=mx,my<=10; |mx|+|my|>0), which means that if a knight stands at (x,y), it can move to (x+mx,y+my).

Output

Output one line for each test case. It contains an integer indicating the least number of moves needed for the knight to reach its destination. Output "IMPOSSIBLE" if the knight may never gets to its target position.

Sample Input

2
0 0 6 6
5
1 2
2 1
2 2
1 3
3 1
0 0 5 5
2
1 2
2 1

Sample Output

3 
IMPOSSIBLE 

Description: Here you start and end points and m kinds of moves, asked if he reaches the end, if the output of the shortest number of steps.
Analysis: This is a simple question at first glance the BFS, but he did not limit the size of the search for "chessboard", and will direct the bare T, then we will make reasonable pruning, removing some cases impossible.
1. If the point is away from the start point / end point, shall pruning:
  this should be better understood, the path will not be departing from the shortest path can be determined by law of cosines.
However, if the shortest path is a departure from the first and then come back? We first introduced a conclusion: the order change does not affect the final path to reach the terminal to figure as an example:

In this way, it brings us to our second pruning:

2. Every step must be within the maximum distance of:

Since the number of steps can be freely converted, then we can at each step within the maximum distance limit, so you can limit the infinite distance, converted to a limited, and also the first pruning can not determine the case of (not but will not deviate reach) to cut.

PS: when calculating the distance using a linear distance to the point of formula ( dreams school

This problem also that we have to hand it hash, would use T STL, refer to the separate law on the black book link (data structure and algorithm analysis).

(I have not read the welcome message, limited literary skills ..)

code show as below:

#define sqr(x) ((x) * (x))
const int prime = 999997;

int T, sx, sy, ex, ey, n, order[15][2], head[prime], idx, length;
double A, B, C, d; // Ax+By+C=0

struct Node {
    int x, y, step;
};

struct unit {
    int x, y, next;
} edge[400000];

int Hash(int x,int y) {
    return (((x << 13) ^ 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 check(int x,int y) {
    int t1 = sqr(x - sx) + sqr(y - sy);
    int t2 = sqr(ex - x) + sqr(ey - y);
    double t3 = sqr(A * x + B * y + C) * 1.0 / ((sqr(A) + sqr(B)) * 1.0);
    if(t2 > t1 + length || t1 > t2 + length)   // 情况1
        return false;
    if(t3 <= d)
        return true;    // 情况2
    return false;
}

bool bfs() {
    queue<Node> q;
    Node p, tmp;
    p.x = sx, p.y = sy, p.step = 0;
    q.push(p);
    addedge(Hash(sx, sy), sx, sy);
    while(!q.empty()) {
        p = q.front(), q.pop();
        if(p.x == ex && p.y == ey) {
            printf("%d\n", p.step);
            return true;
        }
        for (int i = 0; i < n; ++i) {
            tmp = p;
            tmp.x += order[i][0], tmp.y += order[i][1];
            if(check(tmp.x,tmp.y)&&addedge(Hash(tmp.x,tmp.y),tmp.x,tmp.y)) {
                tmp.step++;
                q.push(tmp);
            }
        }
    }
    return false;
}

int main() {
    scanf("%d", &T);
    while(T--) {
        d = 0, idx = 0;
        scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
        scanf("%d", &n);
        for (int i = 0; i < n; ++i) {
            scanf("%d%d", &order[i][0], &order[i][1]);
            d = max(d, sqr(order[i][0]) + sqr(order[i][1])*1.0);
        }
        A = ey - sy, B = sx - ex, C = ex * sy - ey * sx;
        length = sqr(ex - sy) + sqr(ey - sy);
        memset(head, -1, sizeof(head));
        if(!bfs())
            printf("IMPOSSIBLE\n");
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/GRedComeT/p/11228396.html