题意:给一个地图,孙悟空(K)救唐僧(T),地图中'S'表示蛇,第一次到这要杀死蛇(蛇最多5条),多花费一分钟,'1'~'m'表示m个钥匙(m<=9),孙悟空要依次拿到这m个钥匙,然后才能去救唐僧,集齐m个钥匙之前可以经过唐僧,集齐x个钥匙以前可以经过x+1,x+2..个钥匙,问最少多少步救到唐僧。

解法:BFS,每个节点维护四个值:

x,y : 当前坐标

key :已经集齐了key个钥匙

step:已经走了多少步

S :   蛇的访问状态 (2^5的数表示,某位为1表示已经杀过了)

然后把唐僧看做钥匙m+1,再加点优化:

为了避免超时,用一个全局的dis[x][y][key][S] 表示到(x,y),已经集齐到key个钥匙,蛇的访问状态为S时的最小步数,如果BFS扩展的时候,当前状态的步数>=dis[当前状态],那么就不再扩展下去了。

BFS中的逻辑就很简单了,看代码吧。

最后,枚举蛇的状态S,取dis[x][y][m+1][S]的最小值即为最小步数。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#define INF 0x3f3f3f3f
using namespace std;
#define N 1000007 int dis[][][][],Stot,M;
struct node
{
int x,y,key,step,S;
};
int dx[] = {,,,-};
int dy[] = {,-,,};
map<pair<int,int>,int> snake;
char ss[][];
int n,m; bool OK(int nx,int ny)
{
if(nx < n && nx >= && ny < n && ny >= && ss[nx][ny] != '#')
return true;
return false;
} void bfs(node s)
{
queue<node> que;
que.push(s);
while(!que.empty())
{
node now = que.front();
que.pop();
int nx = now.x, ny = now.y;
int key = now.key, step = now.step;
int S = now.S;
node tmp;
for(int k=;k<;k++)
{
int kx = nx + dx[k];
int ky = ny + dy[k];
if(!OK(kx,ky)) continue;
tmp.x = kx,tmp.y = ky;
if(ss[kx][ky] == 'S') //蛇
{
int ind = snake[make_pair(kx,ky)]; //是第几条蛇
tmp.key = key;
if(S & (<<(ind-))) //如果已经杀死
{
tmp.S = S;
tmp.step = step+;
}
else //否则要杀
{
tmp.S = S|(<<(ind-));
tmp.step = step+;
}
if(tmp.step < dis[kx][ky][tmp.key][tmp.S])
{
dis[kx][ky][tmp.key][tmp.S] = tmp.step;
que.push(tmp);
}
}
else if(ss[kx][ky] >= '' && ss[kx][ky] <= '') //钥匙点
{
int num = ss[kx][ky] - '';
tmp.step = step+;
tmp.S = S;
if(num == key+) //正好是要拿的那个
tmp.key = key+;
else
tmp.key = key;
if(tmp.step < dis[kx][ky][tmp.key][tmp.S])
{
dis[kx][ky][tmp.key][tmp.S] = tmp.step;
que.push(tmp);
}
}
else if(ss[kx][ky] == '$') //唐僧这个点
{
tmp.key = key;
tmp.S = S;
tmp.step = step+;
if(M == key+) //已经集齐了所有钥匙,不再扩展,更新dis即可
dis[kx][ky][M][S] = min(dis[kx][ky][M][S],step+);
else //没有集齐,继续走
que.push(tmp);
}
else if(ss[kx][ky] == '.')
{
tmp.key = key;
tmp.S = S;
tmp.step = step+;
if(tmp.step < dis[kx][ky][tmp.key][tmp.S])
{
dis[kx][ky][tmp.key][tmp.S] = tmp.step;
que.push(tmp);
}
}
}
}
} int main()
{
int Sx,Ex,Sy,Ey;
int i,j;
while(scanf("%d%d",&n,&m)!=EOF && n+m)
{
if(n == )
{
puts("impossible");
continue;
}
snake.clear();
Stot = ;
M = m+;
for(i=;i<n;i++)
{
scanf("%s",ss[i]);
for(j=;j<n;j++)
{
if(ss[i][j] == 'K')
Sx = i,Sy = j, ss[i][j] = '.';
else if(ss[i][j] == 'T')
Ex = i,Ey = j, ss[i][j] = '$';
else if(ss[i][j] == 'S')
snake[make_pair(i,j)] = ++Stot;
}
}
node tmp;
tmp.x = Sx,tmp.y = Sy,tmp.key = ,tmp.step = ,tmp.S = ;
memset(dis,INF,sizeof(dis));
dis[Sx][Sy][][] = ;
bfs(tmp);
int mini = INF;
for(i=;i<(<<Stot);i++)
mini = min(mini,dis[Ex][Ey][M][i]);
if(mini == INF)
puts("impossible");
else
printf("%d\n",mini);
}
return ;
}

HDU 5025 Saving Tang Monk --BFS的更多相关文章

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

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

  2. 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 ...

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

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

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

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

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

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

  6. HDU 5025 Saving Tang Monk

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

  7. 2014 网选 广州赛区 hdu 5025 Saving Tang Monk(bfs+四维数组记录状态)

    /* 这是我做过的一道新类型的搜索题!从来没想过用四维数组记录状态! 以前做过的都是用二维的!自己的四维还是太狭隘了..... 题意:悟空救师傅 ! 在救师父之前要先把所有的钥匙找到! 每种钥匙有 k ...

  8. HDU 5025 Saving Tang Monk(状态转移, 广搜)

    #include<bits/stdc++.h> using namespace std; ; ; char G[maxN][maxN], snake[maxN][maxN]; ]; int ...

  9. HDU 5025:Saving Tang Monk(BFS + 状压)

    http://acm.hdu.edu.cn/showproblem.php?pid=5025 Saving Tang Monk Problem Description   <Journey to ...

随机推荐

  1. IPC机制--Binder

    文章来自 Android技术内幕 系统卷 转:http://www.linuxidc.com/Linux/2011-08/40508.htm 什么是IPC机制以及IPC机制的种类 在Linux中,是以 ...

  2. 初学Node(四)事件循环

    Node中的事件循环 事件循环是Node的核心,正是因为有了事件循环JS才能够在服务端占有一席之地.JS是一种单线程语言,但是它的执行环境是多线程的在加上JS的事件驱动这一特点,使使JS在执行的过程中 ...

  3. ABAP中使用浏览器打开网页

    在SAP ABAP中可以在Screen中嵌入Html control打开网页,也可以通过调用本地的IE浏览器打开. 1.在Screen中嵌入Html control的例子,在系统中有,se38:SAP ...

  4. 打造高仿QQ的友盟反馈界面(MVP模式)

    什么是MVP呢,简单来说就是将view层和逻辑完全独立出来,让逻辑和显示完全独立.本例中就是采用了这种模式,让activity作为view层,activity中涉及了适配器,所以这里尝试让适配器作为P ...

  5. 【原】训练自己haar-like特征分类器并识别物体(1)

    本系列文章旨在学习如何在opencv中基于haar-like特征训练自己的分类器,并且用该分类器用于模式识别.该过程大致可以分为一下几个大步骤: 1.准备训练样本图片,包括正例及反例样本 2.生成样本 ...

  6. 【原】就IOS发布app时如何保护文本资源的一个方法

    近期的一个app是本地的,数据源来自于本地的一个.json文件,里面的数据是这个app的灵魂.近期快发布该app了,很担心发布后的.ipa包被竞争者解开然后信息发生泄漏.我的处理策略是:打包的时候放的 ...

  7. iOS中倒计时

    方法一:使用NSTimer来实现(比较适用于发送短信验证码倒计时) 主要是利用NSTimer的scheduledTimerWithTimeInterval方法来每秒执行一次changeTime方法 / ...

  8. spring生命周期

    Github地址 最近在整合mybatis-spring. 公司里面已经有一个叫做kylin-datasource的开发包,以前能够提供master和slave2个数据源,最近更新了2.0版本,支持自 ...

  9. Weblogic11g下调WebService出现的一系列问题

    Weblogic11g下调WebService出现的一系列问题 今天在远程测试机上测试前天写的调用WebService接口方法,遇到的问题还真多啊! 首先说明一下weblogic加载jar包的顺序: ...

  10. 【转】App开发者必备的运营、原型、UI设计工具整理

    一.运营类 1. APPVIEW,网址:http://lab.hakim.se/appview/ 帮助iOS 应用开发者追踪所有地区App Store最近的用户评论,可以按时间.评分.地区排序,缺点是 ...