/*
这是我做过的一道新类型的搜索题!从来没想过用四维数组记录状态!
以前做过的都是用二维的!自己的四维还是太狭隘了..... 题意:悟空救师傅 ! 在救师父之前要先把所有的钥匙找到!
每种钥匙有 k 种, 每一种有多个! 只要求找到每一种的其中一个就可以!
找钥匙的顺序按照 第1种, 第2种, 第3种 ....第k种!
找钥匙的时间是一步, 走到相邻空地的时间是一步, 打蛇的时间就是两步!
求找到师傅的最少步数! 这里说一下 state[N][N][10][35]表示的含义: ->state[x][y][i][j]
前两维就不用说了,就是地图上的坐标, 第三维表示的是当前找到第几把钥匙
第四维表示的沿着一条路径走到 (x, y)找到 第 i 把钥匙打掉了哪几条蛇!
将 j 拆分成 二进制, 从右往左数, 如果第 k 为是1, 表示第 k 条 蛇杀掉了!
*/ #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue> #define N 105
using namespace std; char mp[][]; bool state[N][N][][]; int bx, by; struct node{
int x, y;
int numk, snk;
int step;
node(){} node(int x, int y, int numk, int snk, int step){
this->x = x;
this->y = y;
this->numk = numk;
this->snk = snk;
this->step = step;
}
}; int n, m;
int dir[][] = {, , , , -, , , -};
bool operator < (node a, node b) {
return a.step > b.step;
} priority_queue<node>q; bool bfs(){
while(!q.empty()) q.pop();
memset(state, false, sizeof(state));
q.push( node(bx, by, , , ) );
state[bx][by][][] = true;
while( !q.empty() ) {
node cur = q.top();
q.pop();
for(int i=; i<; ++i){
int x = cur.x + dir[i][];
int y = cur.y + dir[i][];
if(x< || x>n || y< || y>n || mp[x][y]=='#') continue;
int numk = cur.numk, snk = cur.snk, step = cur.step;
if(mp[x][y] == '.')
step += ;
else if( mp[x][y] >= '' && mp[x][y] <= ''){
if( numk + == mp[x][y] - '' )
numk += ;
step += ;
}
else if( mp[x][y] >= 'A' && mp[x][y] <= 'E' ){//这一步是关键
int cnt = mp[x][y] - 'A' + ;
if( ( << (cnt-) ) & snk ) step += ;//如果这一条蛇已经被打过了,也就是一条路又折回到这一个点
else{//在这一条路上,这条蛇没有被打过,那就将它打掉,并标记这条蛇打过了!
step += ;
snk ^= ( << (cnt-) );
}
}
else if( mp[x][y] == 'T' && numk == m ){
printf("%d\n", step + );
return true;
}
else step += ; if( state[x][y][numk][snk] ) continue;
state[x][y][numk][snk] = true;
q.push( node(x, y, numk, snk, step) );
}
}
return false;
} int main(){
while( scanf("%d%d", &n, &m) && (n ||m) ) {
int cntS = ;
for(int i = ; i <= n; ++ i){
scanf("%s", mp[i] + );
for(int j = ; j <=n; ++ j)
if(mp[i][j] == 'K'){
bx = i;
by = j;
}
else if(mp[i][j] == 'S')
mp[i][j] = 'A' + cntS++;
}
if( !bfs() ) printf("impossible\n");
}
return ;
}

2014 网选 广州赛区 hdu 5025 Saving Tang Monk(bfs+四维数组记录状态)的更多相关文章

  1. 2014 网选 广州赛区 hdu 5023 A Corrupt Mayor's Performance Art

    #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #d ...

  2. HDU 5025 Saving Tang Monk --BFS

    题意:给一个地图,孙悟空(K)救唐僧(T),地图中'S'表示蛇,第一次到这要杀死蛇(蛇最多5条),多花费一分钟,'1'~'m'表示m个钥匙(m<=9),孙悟空要依次拿到这m个钥匙,然后才能去救唐 ...

  3. hdu 5025 Saving Tang Monk 状态压缩dp+广搜

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092939.html 题目链接:hdu 5025 Saving Tang Monk 状态压缩 ...

  4. HDU 5025 Saving Tang Monk 【状态压缩BFS】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=5025 Saving Tang Monk Time Limit: 2000/1000 MS (Java/O ...

  5. [ACM] HDU 5025 Saving Tang Monk (状态压缩,BFS)

    Saving Tang Monk Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  6. ACM学习历程—HDU 5025 Saving Tang Monk(广州赛区网赛)(bfs)

    Problem Description <Journey to the West>(also <Monkey>) is one of the Four Great Classi ...

  7. hdu 5025 Saving Tang Monk(bfs+状态压缩)

    Description <Journey to the West>(also <Monkey>) is one of the Four Great Classical Nove ...

  8. HDU 5025 Saving Tang Monk

    Problem Description <Journey to the West>(also <Monkey>) is one of the Four Great Classi ...

  9. 2014 网选 上海赛区 hdu 5047 Sawtooth

    题意:求n个'M'型的折线将一个平面分成的最多的面数! 思路:我们都知道n条直线将一个平面分成的最多平面数是 An = An-1 + n+1 也就是f(n) = (n*n + n +2)/2 对于一个 ...

随机推荐

  1. Android shape 渐变!描边!圆角!示例详解

    看看shape的用法,确实很有帮助.这里我偷懒转一篇比较详细的帖子,和大家一起进步~! Android 中常常使用shape来定义控件的一些显示属性,今天看了一些shape的使用,对shape有了大体 ...

  2. VS2010几款超赞的扩展辅助工具总结

    详情请查看http://www.aehyok.com/Blog/Detail/72.html 个人网站地址:aehyok.com QQ 技术群号:206058845,验证码为:aehyok 本文文章链 ...

  3. 新版PHP 7效能實測:Drupal 7能快70%,碎形計算大勝Ruby和Python

    PHP 7才剛在12月3日正式釋出,網頁開發框架Zend公司立刻發表了一份PHP新舊版效能大車拼報告,除了PHP 7和PHP 5.6之外,也把HHVM 3.7版納入一起比較. Zend公司選擇了幾套知 ...

  4. 迅美VPS安装和配置MySQL数据库教程

    MySQL相关教程与知识:    迅美VPS安装和配置MySQL数据库教程    navicat8管理MySQL教程-创建数据库和导入数据    navicat8管理MySQL教程-管理建立用户和分配 ...

  5. Java 对文件的操作

    public class ReadFile { /** * 按行读取文件操作 * @throws IOException */ public void readFile(String fileName ...

  6. 传统认知PK网络认知 刚子扯谈烤串认知

    文/刚子 2013.7.23 提到认知,有太多的介绍,我就不在秀理论文字了,那样等于自我抄袭式的传播给大家,对于大家也没意思,可以推荐大家到百度里面搜索下”认知结构”,介绍的比我详细.同行老陈说的! ...

  7. MongoDB副本集配置系列八:MongoDB监控

    1:Mongostat MongoDB2.6版本 MongoDB3.0版本 2:db.setProfilingLevel(2):打开profiler 类似于MySQL的slow log Profile ...

  8. JAVA Builder模式构建MAP/LIST的示例

    我们在构建一个MAP时,要不停的调用put,有时候看着觉得很麻烦,刚好,看了下builder模式,觉得这思路不错,于是乎,照着用builder模式写了一个构建MAP的示例,代码如下: import j ...

  9. Android的Activity屏幕切换动画(一)-左右滑动切换

    (国内知名Android开发论坛eoe开发者社区推荐:http://www.eoeandroid.com/) Android的Activity屏幕切换动画(一)-左右滑动切换 在Android开发过程 ...

  10. 在redis一致性hash(shard)中使用lua脚本的坑

    redis 2.8之前的版本,为了实现支持巨量数据缓存或者持久化,一般需要通过redis sharding模式来实现redis集群,普遍大家使用的是twitter开源的Twemproxy. twemp ...