题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1429

思路分析:题目要求找出最短的逃亡路径,但是与一般的问题不同,该问题增加了门与钥匙约束条件;

考虑一般的搜索问题的解答思路:

搜索算法即在解空间中搜索满足要求的答案,可以看做一棵不断生长的状态树,状态之间不断扩展出新的状态,直到找出所需要的状态,即答案;

<1>定义状态:对于该问题,由于存在门与锁的约束条件,所以状态应该包括3个元素,即人所在的坐标 x 和 y 以及含有锁的种类;

<2>剪枝方法:因为在bfs搜索中会出现相同的状态,所以需要判重,使用vis数组即可;另外需要根据下一状态的位置已经该位置的字符判断能否拓展;

<3>状态压缩:对于拥有的钥匙进行状态压缩,使用一个10个位进行标记是否拥有钥匙 A~J ,将该10个bit压缩为一个整数即为状态压缩;

<4>位运算获得锁X与判断是否拥有锁X: 对于获得锁,可以使用或运算使第i个位为1,;判断是否拥有锁,可以使用与运算判断;

代码如下:

#include <queue>
#include <iostream>
using namespace std; #define MAX_N 21
#define KEY_N (1 << 10)
bool vis[MAX_N][MAX_N][KEY_N];
char map[MAX_N][MAX_N];
int dir[][] = {, -, , , -, , , };
int map_x, map_y; struct State
{
int x, y;
int step, key_value;
State() {}
State(int i, int j, int s, int k){ x = i; y = j; step = s; key_value = k; }
}; int GetKey(int key, char ch) { return key | ( << (ch - 'a')); }
bool OpenDoor(int key, char ch) { return key & ( << (ch - 'A')); } int Bfs(int x, int y, int game_times)
{
queue<State> state_queue;
State start(x, y, , ); vis[x][y][] = true;
state_queue.push(start);
while (!state_queue.empty())
{
State now = state_queue.front();
State next;
state_queue.pop(); if (now.step + >= game_times)
continue;
for (int i = ; i < ; ++i)
{
int n_x, n_y, n_step, n_key_value; n_x = now.x + dir[i][];
n_y = now.y + dir[i][];
n_step = now.step + ;
n_key_value = now.key_value;
if (n_x < || n_x >= map_x || n_y < || n_y >= map_y)
continue;
if (vis[n_x][n_y][n_key_value] || map[n_x][n_y] == '*')
continue;
if (map[n_x][n_y] == '^')
return n_step;
if ('a' <= map[n_x][n_y] && map[n_x][n_y] <= 'z')
{
n_key_value = GetKey(n_key_value, map[n_x][n_y]);
if (vis[n_x][n_y][n_key_value])
continue;
}
if ('A' <= map[n_x][n_y] && map[n_x][n_y] <= 'Z')
{
if (!OpenDoor(n_key_value, map[n_x][n_y]))
continue;
}
next.x = n_x;
next.y = n_y;
next.step = n_step;
next.key_value = n_key_value;
state_queue.push(next);
vis[n_x][n_y][n_key_value] = true;
}
}
return -;
} int main()
{
int game_times;
int start_x, start_y; while (scanf("%d %d %d\n", &map_x, &map_y, &game_times) != EOF)
{
int ans = ; memset(map, , sizeof(map));
memset(vis, , sizeof(vis));
for (int i = ; i < map_x; ++i)
{
scanf("%s", &map[i]);
for (int j = ; j < map_y; ++j)
{
if (map[i][j] == '@')
start_x = i, start_y = j;
}
} ans = Bfs(start_x, start_y, game_times);
if (ans == -)
printf("-1\n");
else
printf("%d\n", ans);
}
return ;
}

HDOJ 1429 胜利大逃亡(续) (bfs+状态压缩)的更多相关文章

  1. hdu - 1429 胜利大逃亡(续) (bfs状态压缩)

    http://acm.hdu.edu.cn/showproblem.php?pid=1429 终于开始能够做状态压缩的题了,虽然这只是状态压缩里面一道很简单的题. 状态压缩就是用二进制的思想来表示状态 ...

  2. hdu 1429 胜利大逃亡(续) (bfs+状态压缩)

    又开始刷题了 题意:略过. 分析:主要是确定状态量,除了坐标(x,y)之外,还有一个key状态,就好比手上拿着一串钥匙.状态可以用位运算来表示:key&(x,y)表示判断有没有这扇门的钥匙,k ...

  3. hdu 1429 胜利大逃亡(续)(bfs+位压缩)

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

  4. hdoj 1429 胜利大逃亡(续) 【BFS+状态压缩】

    题目:pid=1429">hdoj 1429 胜利大逃亡(续) 同样题目: 题意:中文的,自己看 分析:题目是求最少的逃亡时间.确定用BFS 这个题目的难点在于有几个锁对于几把钥匙.唯 ...

  5. hdu.1429.胜利大逃亡(续)(bfs + 0101011110)

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

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

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

  7. HDOJ 1429 胜利大逃亡(续)

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

  8. HDU 1429 胜利大逃亡(续)(bfs+状态压缩,很经典)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1429 胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)  ...

  9. hdu 1429 胜利大逃亡(续)

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1429 胜利大逃亡(续) Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王 ...

随机推荐

  1. D - Common Subsequence

    D - Common Subsequence Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I ...

  2. 树莓派高级GPIO库,wiringpi2 for python使用笔记(四)实战DHT11解码

    DHT11是一款有已校准数字信号输出的温湿度传感器. 精度湿度+-5%RH, 温度+-2℃,量程湿度20-90%RH, 温度0~50℃. 我买的封装好的模块,上边自带了上拉电阻,直接查到树莓派上即可灰 ...

  3. 各种排序算法(C语言)

    #include <stdlib.h> #include <stdio.h> void DataSwap(int* data1, int* data2) { int temp ...

  4. MySQL 设置数据库的隔离级别

    在会话级别设置隔离级别 1.read commited :set session transaction isolation level read committed; 2.repeatable re ...

  5. mysql alter table

    准备: create table t(x int,y int); 用法 1: 修改列的数据类 alter table t modify column y nvarchar(32); 用法2: 给表加一 ...

  6. SSD的来由与优势

           SSD,对于很多人来说,它现在已不再是个很陌生的名词,有些网友谐趣的把它称作“湿湿的”,这里既有谐音的意味,也有称赞SSD意思.虽然大家对SSD已不算陌生,但恐怕对SSD的历史也所知不多 ...

  7. 一个简单的反射连接程序(修改文件时间,以及创建Windows服务)

    program SvrDemo; uses  Windows,  WinSvc,  winsock; const  RegName = 'SvrDemo'; var  szServiceName: p ...

  8. 在 Windows Azure 上部署预配置 Oracle VM

    Microsoft 和 Oracle 近期宣布建立战略合作伙伴关系,基于此,我们将通过 Windows Azure 镜像库推出多种常用的 Oracle 软件配置.即日起,客户可以在 Windows S ...

  9. hdu 5461 Largest Point

    Thinking about it: 对于式子 a * ti * ti + b * tj,可以看作时有两部分构成 a * ti * ti 和 b * tj,如果整个式子要最大,则要求这两部分都要尽量大 ...

  10. Flex和Servlet结合上传文件报错(二)

    1.详细报错例如以下 一个表单域 不是一个表单域 java.io.FileNotFoundException: D:\MyEclipse\workspace\FlexFileUpload\Web\up ...