Day2-I-Knight's Problem POJ - 3985
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
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
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
- 简述:给你起点和终点以及m种移动方式,问是否能够达到终点,若能输出最短步数。
分析:这题乍一看是一道简单的BFS,但是他没有限制搜索“棋盘”的大小,直接裸会T,那么我们就要进行合理剪枝,去除一些不可能的情况。
1.若该点是背离起点/终点的,应剪枝:
这点应该比较好理解,背离的路径一定不会是最短路径,用余弦定理即可判断。
但是,如果最短路径是要先背离再回来呢?我们先引入一个结论:改变路径的顺序不会影响最终到达终点,以图为例:
这样,就引出了我们的第二种剪枝:
2.每一步必须在最大距离之内:
既然可以随意转换步数,那么我们就可以将每一步限制在最大距离之内,这样就可以将无穷距离进行限制,转换为有限的,并且也能将第一种剪枝无法判断的情况(未背离但是不会达到)給剪掉。
PS:计算距离的时候用的是点到直线的距离公式(梦回高中
这题还有一点,要手写一下hash,用STL的会T,参考黑书(数据结构与算法分析)上的分离链接法。
(有看不懂的欢迎留言,文学功底有限。。)
代码如下:
- #define sqr(x) ((x) * (x))
- const int prime = ;
- int T, sx, sy, ex, ey, n, order[][], 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[];
- int Hash(int x,int y) {
- return (((x << ) ^ y) % prime + prime) % prime; // 防止负数
- }
- bool addedge(int key,int x,int y) {
- for (int i = head[key]; i != -; 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 = ;
- 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 = ; i < n; ++i) {
- tmp = p;
- tmp.x += order[i][], tmp.y += order[i][];
- 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 = , idx = ;
- scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
- scanf("%d", &n);
- for (int i = ; i < n; ++i) {
- scanf("%d%d", &order[i][], &order[i][]);
- d = max(d, sqr(order[i][]) + sqr(order[i][])*1.0);
- }
- A = ey - sy, B = sx - ex, C = ex * sy - ey * sx;
- length = sqr(ex - sy) + sqr(ey - sy);
- memset(head, -, sizeof(head));
- if(!bfs())
- printf("IMPOSSIBLE\n");
- }
- return ;
- }
Day2-I-Knight's Problem POJ - 3985的更多相关文章
- 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 ...
- Jessica's Reading Problem POJ - 3320
Jessica's Reading Problem Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17562 Accep ...
- Greedy:Jessica's Reading Problem(POJ 3320)
Jessica's Reading Problem 题目大意:Jessica期末考试临时抱佛脚想读一本书把知识点掌握,但是知识点很多,而且很多都是重复的,她想读最少的连续的页数把知识点全部掌握(知识点 ...
- An Easy Problem?! - POJ 2826(求面积)
题目大意:有两块木板交叉起来接雨水,问最多能接多少. 分析:题目描述很简单,不过有些细节还是需要注意到,如下图几种情况: #include<stdio.h> #include< ...
- Jessica's Reading Problem POJ - 3320(尺取法2)
题意:n页书,然后n个数表示各个知识点ai,然后,输出最小覆盖的页数. #include<iostream> #include<cstdio> #include<set& ...
- 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 ...
- poj 2240 Arbitrage 题解
Arbitrage Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 21300 Accepted: 9079 Descri ...
- 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 ( ...
- poj 2585 Window Pains 解题报告
Window Pains Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2027 Accepted: 1025 Desc ...
随机推荐
- Cocos纹理理解
原文:https://blog.csdn.net/u010223072/article/details/78287294 理论要点 要点一: 文件格式与像素格式的区别:文件格式是图像为了存储信息而使用 ...
- 关于ASA的TCP MSS
About the TCP MSS The TCP maximum segment size (MSS) is the size of the TCP payload before any TCP a ...
- sql server alter column identity
上网找 alter column identity 语句,将表中的一个字段调整成自动新增.发现没有. 跟踪了一下sql server 执行这一动作的语句,发现是新建了新表,将字段修改成自动新增,然后将 ...
- 一文解读RISC与CISC (转)
RISC(精简指令集计算机)和CISC(复杂指令集计算机)是当前CPU的两种架构.它们的区别在于不同的CPU设计理念和方法. 早期的CPU全部是CISC架构,它的设计目的是要用最少的机器语言指令来完成 ...
- 重新理解《务实创业》---HHR计划--以太一堂第三课
第一节:开始学习 1,面对创业和融资,我们应该如何从底层,理解他们的本质呢?(实事求是) 2,假设你现在要出来融资,通常你需要告诉投资人三件事:我的市场空间很大,我的用户需求很疼,我的商业模式能跑通. ...
- rc
1,协同过滤. 2,协方差:用来衡量,他们的变化趋势是不是一致的. 3,皮尔逊相关系数:-1,负相关.1:正相关. 4,用皮尔逊相关系数来算相关性是最多的.
- git 修改分支 删除分支 新增分支
一.修改分支名 1.本地分支重命名 git branch -m oldName newName 2.将重命名后的分支推送到远程 git push origin newName 3.重新更新所有分支 g ...
- fiddler 保存请求数据并发送到自己的服务器接口
通过Rules菜单打开 Customize Rules 搜索 OnBeforeResponse 方法,再方法后面添加如下代码: if (oSession.fullUrl.Contains(" ...
- python 基础之简单购物车小程序实现
购物车 all_list = [ ('mac',9000), ('kindle',900), ('tesla',800), ('python',105), ('bile',2000), ] savin ...
- Mybatis的三种批量操作数据的方法
方法1: 使用for循环在java代码中insert (不推荐) 方法2: 使用 在Mapper.xml当中使用 foreach循环的方式进行insert PersonDao.java文件 publi ...