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

  1. 2
  2. 0 0 6 6
  3. 5
  4. 1 2
  5. 2 1
  6. 2 2
  7. 1 3
  8. 3 1
  9. 0 0 5 5
  10. 2
  11. 1 2
  12. 2 1

Sample Output

  1. 3
  2. IMPOSSIBLE
  3.  
  4. 简述:给你起点和终点以及m种移动方式,问是否能够达到终点,若能输出最短步数。
    分析:这题乍一看是一道简单的BFS,但是他没有限制搜索“棋盘”的大小,直接裸会T,那么我们就要进行合理剪枝,去除一些不可能的情况。
    1.若该点是背离起点/终点的,应剪枝:
      这点应该比较好理解,背离的路径一定不会是最短路径,用余弦定理即可判断。
    但是,如果最短路径是要先背离再回来呢?我们先引入一个结论:改变路径的顺序不会影响最终到达终点,以图为例:

这样,就引出了我们的第二种剪枝:

2.每一步必须在最大距离之内:

既然可以随意转换步数,那么我们就可以将每一步限制在最大距离之内,这样就可以将无穷距离进行限制,转换为有限的,并且也能将第一种剪枝无法判断的情况(未背离但是不会达到)給剪掉。

PS:计算距离的时候用的是点到直线的距离公式(梦回高中

这题还有一点,要手写一下hash,用STL的会T,参考黑书(数据结构与算法分析)上的分离链接法。

(有看不懂的欢迎留言,文学功底有限。。)

代码如下:

  1. #define sqr(x) ((x) * (x))
  2. const int prime = ;
  3.  
  4. int T, sx, sy, ex, ey, n, order[][], head[prime], idx, length;
  5. double A, B, C, d; // Ax+By+C=0
  6.  
  7. struct Node {
  8. int x, y, step;
  9. };
  10.  
  11. struct unit {
  12. int x, y, next;
  13. } edge[];
  14.  
  15. int Hash(int x,int y) {
  16. return (((x << ) ^ y) % prime + prime) % prime; // 防止负数
  17. }
  18.  
  19. bool addedge(int key,int x,int y) {
  20. for (int i = head[key]; i != -; i = edge[i].next) {
  21. if(edge[i].x == x && edge[i].y == y)
  22. return false;
  23. }
  24. edge[idx].x = x, edge[idx].y = y;
  25. edge[idx].next = head[key];
  26. head[key] = idx++;
  27. return true;
  28. }
  29.  
  30. bool check(int x,int y) {
  31. int t1 = sqr(x - sx) + sqr(y - sy);
  32. int t2 = sqr(ex - x) + sqr(ey - y);
  33. double t3 = sqr(A * x + B * y + C) * 1.0 / ((sqr(A) + sqr(B)) * 1.0);
  34. if(t2 > t1 + length || t1 > t2 + length) // 情况1
  35. return false;
  36. if(t3 <= d)
  37. return true; // 情况2
  38. return false;
  39. }
  40.  
  41. bool bfs() {
  42. queue<Node> q;
  43. Node p, tmp;
  44. p.x = sx, p.y = sy, p.step = ;
  45. q.push(p);
  46. addedge(Hash(sx, sy), sx, sy);
  47. while(!q.empty()) {
  48. p = q.front(), q.pop();
  49. if(p.x == ex && p.y == ey) {
  50. printf("%d\n", p.step);
  51. return true;
  52. }
  53. for (int i = ; i < n; ++i) {
  54. tmp = p;
  55. tmp.x += order[i][], tmp.y += order[i][];
  56. if(check(tmp.x,tmp.y)&&addedge(Hash(tmp.x,tmp.y),tmp.x,tmp.y)) {
  57. tmp.step++;
  58. q.push(tmp);
  59. }
  60. }
  61. }
  62. return false;
  63. }
  64.  
  65. int main() {
  66. scanf("%d", &T);
  67. while(T--) {
  68. d = , idx = ;
  69. scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
  70. scanf("%d", &n);
  71. for (int i = ; i < n; ++i) {
  72. scanf("%d%d", &order[i][], &order[i][]);
  73. d = max(d, sqr(order[i][]) + sqr(order[i][])*1.0);
  74. }
  75. A = ey - sy, B = sx - ex, C = ex * sy - ey * sx;
  76. length = sqr(ex - sy) + sqr(ey - sy);
  77. memset(head, -, sizeof(head));
  78. if(!bfs())
  79. printf("IMPOSSIBLE\n");
  80. }
  81. return ;
  82. }

Day2-I-Knight's Problem POJ - 3985的更多相关文章

  1. A - Jessica's Reading Problem POJ - 3320 尺取

    A - Jessica's Reading Problem POJ - 3320 Jessica's a very lovely girl wooed by lots of boys. Recentl ...

  2. Jessica's Reading Problem POJ - 3320

    Jessica's Reading Problem Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17562   Accep ...

  3. Greedy:Jessica's Reading Problem(POJ 3320)

    Jessica's Reading Problem 题目大意:Jessica期末考试临时抱佛脚想读一本书把知识点掌握,但是知识点很多,而且很多都是重复的,她想读最少的连续的页数把知识点全部掌握(知识点 ...

  4. An Easy Problem?! - POJ 2826(求面积)

    题目大意:有两块木板交叉起来接雨水,问最多能接多少.   分析:题目描述很简单,不过有些细节还是需要注意到,如下图几种情况:   #include<stdio.h> #include< ...

  5. Jessica's Reading Problem POJ - 3320(尺取法2)

    题意:n页书,然后n个数表示各个知识点ai,然后,输出最小覆盖的页数. #include<iostream> #include<cstdio> #include<set& ...

  6. Day6 - I - Sticks Problem POJ - 2452

    Xuanxuan has n sticks of different length. One day, she puts all her sticks in a line, represented b ...

  7. poj 2240 Arbitrage 题解

    Arbitrage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 21300   Accepted: 9079 Descri ...

  8. HDU1372 Knight Moves(BFS) 2016-07-24 14:50 69人阅读 评论(0) 收藏

    Knight Moves Problem Description A friend of you is doing research on the Traveling Knight Problem ( ...

  9. poj 2585 Window Pains 解题报告

    Window Pains Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2027   Accepted: 1025 Desc ...

随机推荐

  1. Cocos纹理理解

    原文:https://blog.csdn.net/u010223072/article/details/78287294 理论要点 要点一: 文件格式与像素格式的区别:文件格式是图像为了存储信息而使用 ...

  2. 关于ASA的TCP MSS

    About the TCP MSS The TCP maximum segment size (MSS) is the size of the TCP payload before any TCP a ...

  3. sql server alter column identity

    上网找 alter column identity 语句,将表中的一个字段调整成自动新增.发现没有. 跟踪了一下sql server 执行这一动作的语句,发现是新建了新表,将字段修改成自动新增,然后将 ...

  4. 一文解读RISC与CISC (转)

    RISC(精简指令集计算机)和CISC(复杂指令集计算机)是当前CPU的两种架构.它们的区别在于不同的CPU设计理念和方法. 早期的CPU全部是CISC架构,它的设计目的是要用最少的机器语言指令来完成 ...

  5. 重新理解《务实创业》---HHR计划--以太一堂第三课

    第一节:开始学习 1,面对创业和融资,我们应该如何从底层,理解他们的本质呢?(实事求是) 2,假设你现在要出来融资,通常你需要告诉投资人三件事:我的市场空间很大,我的用户需求很疼,我的商业模式能跑通. ...

  6. rc

    1,协同过滤. 2,协方差:用来衡量,他们的变化趋势是不是一致的. 3,皮尔逊相关系数:-1,负相关.1:正相关. 4,用皮尔逊相关系数来算相关性是最多的.

  7. git 修改分支 删除分支 新增分支

    一.修改分支名 1.本地分支重命名 git branch -m oldName newName 2.将重命名后的分支推送到远程 git push origin newName 3.重新更新所有分支 g ...

  8. fiddler 保存请求数据并发送到自己的服务器接口

    通过Rules菜单打开 Customize Rules 搜索 OnBeforeResponse 方法,再方法后面添加如下代码: if (oSession.fullUrl.Contains(" ...

  9. python 基础之简单购物车小程序实现

    购物车 all_list = [ ('mac',9000), ('kindle',900), ('tesla',800), ('python',105), ('bile',2000), ] savin ...

  10. Mybatis的三种批量操作数据的方法

    方法1: 使用for循环在java代码中insert (不推荐) 方法2: 使用 在Mapper.xml当中使用 foreach循环的方式进行insert PersonDao.java文件 publi ...