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 ...
随机推荐
- Spring学习(八)
AOP的重要概念 1.切面 : 切点(Pointcut) + Advice[ 在哪里 .加什么 ] 2.Advice: 在 切点 选中的 连接点 "加入" 的 代码 就是 Advi ...
- 【转载】Eclipse 最常用快捷键 (动画讲解),最简单的一些快捷键
Eclipse有强大的编辑功能, 工欲善其事,必先利其器, 掌握Eclipse快捷键,可以大大提高工作效率. 小坦克我花了一整天时间, 精选了一些常用的快捷键操作,并且精心录制了动画, 让你一看就会. ...
- SVN安装不成功,提示Invalid driver H:
本来我的SVN安装在H盘,后来我把包含H盘的硬盘下下来了,这样H盘就不存在了. 这时候我想重新安装SVN,点击安装包,结果提示Invalid driver H,怎么都不能安装成功. 这时候我去注册表里 ...
- jenkins windows 2.204版,免安装,推荐插件齐备.
windows专用,已安装好推荐插件, 更新了安装源为清华源,也就是说只要官方的插件,你都可以秒速下载了.香不? 解压到一个文件夹,管理员模式运行cmdcd 文件夹名jenkins install这样 ...
- Mysql基本用法-01
#登录数据库 mysql -hlocalhost -uroot -p; #修改密码 mysqladmin -uroot -pold password new; #显示数据库 show database ...
- Tensorflow机器学习入门——AttributeError: module 'scipy.misc' has no attribute 'toimage'
这个bug的解决办法: import cv2 # scipy.misc.toimage(image_array).save('cifar10_data/raw/%d.jpg' % i) cv2.imw ...
- CSS - 背景半透明
就一句话 background: rgba(0, 0, 0, .2); body { background-color: pink; } div { width: 200px; height: 200 ...
- 神奇的 SQL 之 联表细节 → MySQL JOIN 的执行过程
问题背景 对于 MySQL 的 JOIN,不知道大家有没有去想过他的执行流程,亦或有没有怀疑过自己的理解(自信满满的自我认为!):如果大家不知道怎么检验,可以试着回答如下的问题 驱动表的选择 MySQ ...
- 笔记-mongodb-用户及角色
笔记-mongodb-用户及角色 1. users 其实mongodb支持多种验证方式,本文只提及最简单也最常用的方式. 1.1. Authentication Database When ...
- python批量提取哔哩哔哩bilibili视频
# -*- coding: utf-8 -*- """ Created on Tue Jan 29 13:26:41 2019 @author: kwy "&q ...