题目链接

有一个n*m(1<=n,m<=20)的网格图,图中有k堵墙和有一条长度为L(L<=8)的蛇,蛇在移动的过程中不能碰到自己的身体。求蛇移动到点(1,1)所需的最小步数。

显然用8个(x,y)来表示蛇的状态是不现实的(用哈希也很难存下,要么爆内存,要么超时),所以首先应当进行状态压缩。可以发现蛇的身体是连续的,因此可以用一个表示方向的向量来储存蛇身体的每个部分在它上个部分的哪个方向(只有头部用(x,y)表示),这样总状态数就变成了n*m*(2^((L-1)*2)),在可接受范围内了。

可优化的部分:

1.可以在图的边界上放上一层墙,避免出界判定。

2.如果在碰撞判定时把“蛇身”和“墙”等同的话,为了防止在撤销蛇身所造成的影响的同时把墙也一并消除,可以用b[x][y]++,--的方法来代替b[x][y]=1。

AC代码:(编码和解码真是个体力活)

 #include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int N=+;
const int dx[]= {,,-,};
const int dy[]= {-,,,};
struct P {int x,y;} p[N],r[N];
int n,m,l,k,b[N][N],d[N][N][(<<)+],S,ka;
struct D {int x,y,S;}; int bfs() {
queue<D> q;
memset(d,-,sizeof d);
d[p[].x][p[].y][S]=,q.push({p[].x,p[].y,S});
while(!q.empty()) {
int x=q.front().x,y=q.front().y,S=q.front().S;
q.pop();
if(x==&&y==)return d[x][y][S];
r[]= {x,y};
for(int i=; i<l; ++i) {
int t=S>>((l-i-)*)&;
r[i]= {r[i-].x+dx[t],r[i-].y+dy[t]};
}
for(int i=; i<l; ++i)b[r[i].x][r[i].y]++;
for(int i=; i<; ++i) {
int xx=x+dx[i],yy=y+dy[i],SS=S>>|((i^)<<((l-)*));
if(!b[xx][yy]&&!~d[xx][yy][SS])d[xx][yy][SS]=d[x][y][S]+,q.push({xx,yy,SS});
}
for(int i=; i<l; ++i)b[r[i].x][r[i].y]--;
}
return -;
} int main() {
while(scanf("%d%d%d",&n,&m,&l)&&n) {
printf("Case %d: ",++ka);
for(int i=; i<l; ++i)scanf("%d%d",&p[i].x,&p[i].y);
S=;
for(int i=; i<l; ++i)
for(int j=; j<; ++j)if(p[i-].x+dx[j]==p[i].x&&p[i-].y+dy[j]==p[i].y) {
S=S<<|j;
break;
}
memset(b,,sizeof b);
for(int i=; i<=n+; ++i)b[i][]=b[i][m+]=;
for(int i=; i<=m+; ++i)b[][i]=b[n+][i]=;
scanf("%d",&k);
while(k--) {
int x,y;
scanf("%d%d",&x,&y);
b[x][y]=;
}
printf("%d\n",bfs());
}
return ;
}

bfs

也可以进一步用A*优化,以每个点到点(1,1)的距离为估价函数进行转移,速度大幅提升。

一般A*中优先队列的结点要额外设一个属性g来表示已走过的距离,但也可以省去这个g,用d[x][y][S]来代替g,这样如果要把bfs改成A*的话,只要写出求每个点到点(1,1)距离的bfs代码,然后把原来的bfs代码中的queue换成priority_queue,front换成top就ok了,非常方便。

另外可以优化的一个地方是如果一个点不能到达(1,1),那么直接返回-1就行,不用再浪费时间跑A*了。

 #include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int N=+;
const int dx[]= {,,-,};
const int dy[]= {-,,,};
struct P {int x,y;} p[N],r[N];
int n,m,l,k,b[N][N],d[N][N][(<<)+],S,h[N][N],ka;
struct D {
int x,y,S;
bool operator<(const D& b)const {return d[x][y][S]+h[x][y]>d[b.x][b.y][b.S]+h[b.x][b.y];}
}; void bfs() {
queue<P> q;
memset(h,-,sizeof h);
h[][]=,q.push({,});
while(!q.empty()) {
int x=q.front().x,y=q.front().y;
q.pop();
for(int i=; i<; ++i) {
int xx=x+dx[i],yy=y+dy[i];
if(!~h[xx][yy]&&!b[xx][yy])h[xx][yy]=h[x][y]+,q.push({xx,yy});
}
}
} int Astar() {
if(!~h[p[].x][p[].y])return -;
priority_queue<D> q;
memset(d,-,sizeof d);
d[p[].x][p[].y][S]=,q.push({p[].x,p[].y,S});
while(!q.empty()) {
int x=q.top().x,y=q.top().y,S=q.top().S;
q.pop();
if(x==&&y==)return d[x][y][S];
r[]= {x,y};
for(int i=; i<l; ++i) {
int t=S>>((l-i-)*)&;
r[i]= {r[i-].x+dx[t],r[i-].y+dy[t]};
}
for(int i=; i<l; ++i)b[r[i].x][r[i].y]++;
for(int i=; i<; ++i) {
int xx=x+dx[i],yy=y+dy[i],SS=S>>|((i^)<<((l-)*));
if(!b[xx][yy]&&!~d[xx][yy][SS])d[xx][yy][SS]=d[x][y][S]+,q.push({xx,yy,SS});
}
for(int i=; i<l; ++i)b[r[i].x][r[i].y]--;
}
return -;
} int main() {
while(scanf("%d%d%d",&n,&m,&l)&&n) {
printf("Case %d: ",++ka);
for(int i=; i<l; ++i)scanf("%d%d",&p[i].x,&p[i].y);
S=;
for(int i=; i<l; ++i)
for(int j=; j<; ++j)if(p[i-].x+dx[j]==p[i].x&&p[i-].y+dy[j]==p[i].y) {
S=S<<|j;
break;
}
memset(b,,sizeof b);
for(int i=; i<=n+; ++i)b[i][]=b[i][m+]=;
for(int i=; i<=m+; ++i)b[][i]=b[n+][i]=;
scanf("%d",&k);
while(k--) {
int x,y;
scanf("%d%d",&x,&y);
b[x][y]=;
}
bfs();
printf("%d\n",Astar());
}
return ;
}

A*

POJ - 1324 Holedox Moving (状态压缩+BFS/A*)的更多相关文章

  1. POJ 1324 Holedox Moving (状压BFS)

    POJ 1324 Holedox Moving (状压BFS) Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 18091 Acc ...

  2. poj 1324 Holedox Moving

    poj 1324 Holedox Moving 题目地址: http://poj.org/problem?id=1324 题意: 给出一个矩阵中,一条贪吃蛇,占据L长度的格子, 另外有些格子是石头, ...

  3. POJ 1324 Holedox Moving 搜索

    题目地址: http://poj.org/problem?id=1324 优先队列---A*的估价函数不能为蛇头到(1,1)的距离,这样会出错. 看了discuss,有大神说这题A*的估价函数为BFS ...

  4. POJ 3411 Paid Roads (状态压缩+BFS)

    题意:有n座城市和m(1<=n,m<=10)条路.现在要从城市1到城市n.有些路是要收费的,从a城市到b城市,如果之前到过c城市,那么只要付P的钱, 如果没有去过就付R的钱.求的是最少要花 ...

  5. POJ 1753 Flip Game(状态压缩+BFS)

    题目网址:http://poj.org/problem?id=1753 题目: Flip Game Description Flip game is played on a rectangular 4 ...

  6. poj 1324 状态压缩+bfs

    http://poj.org/problem?id=1324 Holedox Moving Time Limit: 5000MS   Memory Limit: 65536K Total Submis ...

  7. 胜利大逃亡(续)(状态压缩bfs)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  8. POJ 1753 Flip Game (状态压缩 bfs+位运算)

    Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 square ...

  9. hdu 3681 Prison Break(状态压缩+bfs)

    Problem Description Rompire . Now it’s time to escape, but Micheal# needs an optimal plan and he con ...

随机推荐

  1. VMware虚拟机NAT模式的具体配置

      NAT模式的具体配置 NAT方式:虚拟机可以上外网,可以访问宿主计算机所在网络的其他计算机(反之不行). 1.1.1.        查看虚拟机的网络参数 1)      打开虚拟机,选择菜单&q ...

  2. 学习OpenCV2——Mat之通道的理解

    本文详细介绍了opencv中涉及通道的知识,包括图像类型转换,通道合成分解,图像的显示. 来源:http://blog.csdn.net/GDFSG/article/details/50927257 ...

  3. spring mvc 自动扫描注解失效原因

    关于spring自动扫描,在控制层,采用注解配置@Controller,项目能够成功启动,且无任何报错.但是 在进行页面跳转时,并未进行相应的拦截,整个界面只能在默认界面 ,跳转报404,由于楼主初次 ...

  4. 实现对第三方应用任意SO注入

    实现对第三方应用任意SO注入 0x01 应用在Android中运行,从外部对该进程可以进行任意SO文件动态注入,就是应用动态运行我们的SO文件 0x02 基本的逻辑是: 1.    获取目标进程的pi ...

  5. Hibernate一对多、多对一关联

    一对多.多对一关联:在多方加外键 示例:Group(一方)和User(多方),一个Group可以有多个User,每个User只能属于一个Group   多对一单向关联 在User(多方)中建Group ...

  6. PHP汉子转拼音

    <?php /** +------------------------------------------------------ * PHP 汉字转拼音 +------------------ ...

  7. GP DBA基本操作

    1.查看队列情况 SELECT * FROM gp_toolkit.gp_resqueue_status; 如果出现了资源占用大于1.1 e+11SQL,则可能存在不合理执行计划的SQL, 基本跑不出 ...

  8. Python编程-多态、封装、特性

    一.多态与多态性 1.多态 (1)什么是多态 多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承) 序列类型有多种形态:字符串,列表,元组. 动物有多种形态:人,狗,猪 文 ...

  9. php数组函数-array_diff()

    array_diff()函数返回两个数组的差集数组.该数组包括了所有在被比较数组中,但是不在任何其他参数数组中的键值在返回数组中,键名保持不变. array_diff(array1,array2,ar ...

  10. 吴恩达深度学习笔记(七) —— Batch Normalization

    主要内容: 一.Batch Norm简介 二.归一化网络的激活函数 三.Batch Norm拟合进神经网络 四.测试时的Batch Norm 一.Batch Norm简介 1.在机器学习中,我们一般会 ...