Problem Description

作为一个强迫症患者,小 Y 在走游戏里的迷宫时一定要把所有的宝箱收集齐才肯罢休。现在给你一个 N *M 的迷宫,里面有障碍、空地和宝箱,小 Y 在某个起始点,每一步小 Y 可以往上下左右走,当然前提时没有走出迷宫并且走到的点不是障碍。如果小 Y 走到了某个为宝箱的点,那么这个宝箱就被他收集到了,然后此处变为空地。 现在你需要计算小 Y 最少需要走多少步才能收集齐所有的宝箱。

Input

输入包含多组数据。 对于每组数据,第一行两个正整数 N;M(1<=N;M<=100),表示迷宫大小。 接下来 N 行,每行 M 个整数,第 i + 1 行的第 j 个整数表示迷宫第 i 行第 j 列的情况,0 表示空地,-1表示障碍,1 表示宝箱,2 表示小Y 的起始点。保证2 只有一个,且宝箱数量不超过5 个。 数据以两个0 表示结尾。

Output

对于每组数据输出一行,包含一个整数,表示小 Y 最少的步数。如果小 Y 无法收集齐所有宝箱,输出-1。

Sample Input

3 5
1 -1 1 -1 2
0 -1 0 -1 0
0 0 0 0 0
0 0

很久之前遇到的题现在又偶然遇到了,当初一直没看懂,现在终于懂了,不过找不到出处在哪了。

因为要收集完所有宝箱,把起点也作为宝箱,然后求出所有宝箱的两两距离,最后枚举所有 的情况求出最小值.

枚举的时候借用了全排列,方法很巧妙。

#include<iostream>
#include<cstring>
#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;
const int M=;
int n,m;
int map[M][M]; //迷宫
struct point
{
int r;
int l;
} p[]; //记录宝箱位置和初始位置
int run[][]= {,,-,,,,,-}; //bfs的方向数组
int bfs(point x,point y) //求两个宝箱的最短距离
{
int r,l,i,now,next,a[M][M]= {},mp[M][M];
queue<int> qu;
now=x.r*m+x.l;
qu.push(now);
for(i=; i<n; i++) //因为要调用计算多次,所以map不能改变,每次用map 初始mp
for(l=; l<m; l++)
mp[i][l]=map[i][l];
while(!qu.empty())
{
now=qu.front();
qu.pop();
for(i=; i<; i++)
{
r=now/m+run[i][];
l=now%m+run[i][];
next=r*m+l;
if(r>= &&r<n && l>= && l<m && mp[r][l]!=-)
{
a[r][l]+=a[now/m][now%m]+;
qu.push(next);
mp[r][l]=-;
if(r==y.r && l==y.l)
return a[r][l];
}
}
}
return -; //不通时返回
}
int main()
{
freopen("a.txt","r",stdin);
int i,j,num,min,dis[M][M];//dis数组保存第i个宝箱到第j个宝箱的最短距离
while(scanf("%d%d",&n,&m)!=EOF && n!= && m!=)
{
memset(dis,,sizeof(dis));
int flag=;//若有宝箱不能到达的标志
min=;
num=;
for(i=; i<n; i++)
for(j=; j<m; j++)
{
cin>>map[i][j];
if(map[i][j]==)
{
p[].r=i;
p[].l=j;
}
if(map[i][j]== )
{
p[num].r=i;
p[num++].l=j;
}
}
for(i=; i<num; i++)
{
for(j=; j<num; j++)
if(i!=j)
{
dis[i][j]=bfs(p[i],p[j]);
if(dis[i][j]==-)
{
flag=;
break;
}
}
if(flag)
break;
}
if(flag)
{
printf("-1\n");
continue;
}
char a[]= {""};
//因为最多有5个宝箱,用这个字符串代表排列的顺序,看下面会懂的,有点妙!
do
{
int s=;
for(i=; i<num-; i++)
{
s+=dis[a[i]-''][a[i+]-''];
}
if(min>s) //判断每种情况,
min=s;
}
while(next_permutation(a+,a+num));
//一个库函数 第一次经过他之后a[6]={"02354"}
printf("%d\n",min);
}
return ;
}

找宝箱 (bfs)的更多相关文章

  1. 【CodeForces - 598D】Igor In the Museum(bfs)

    Igor In the Museum Descriptions 给你一个n*m的方格图表示一个博物馆的分布图.每个方格上用'*'表示墙,用'.'表示空位.每一个空格和相邻的墙之间都有一幅画.(相邻指的 ...

  2. bzoj 1064

    题意:戳这里 思路:很明显是一个图论模型.. 就两种图形: 1.图中存在环,那么就是所有环的gcd为最大答案.gcd的大于3的最小约数为最小答案 2.不存在环,那么是每个弱连通块的最长链之和为最大答案 ...

  3. 圣诞福利到!51Testing邀你一起来狂欢!有礼就是任性~(≧▽≦)/~

    “我想变成一棵树,一棵只为你存在的圣诞树,顶上最大最亮的那颗星是我的真心,下面挂满我对你的祝福. 你的关注是我的幸福,你的肯定是我的力量,而我将用更多精彩的内容,用心的分享,给你下一个一整年的 精彩! ...

  4. NOIP 2009 最优贸易

    题目描述 C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个 城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一部分 为双向通行的道路 ...

  5. 洛谷P1605走迷宫

    传送 这是一道dfs,但是...但是....但是它竟然被放在bfs练习题辣!!!! 打了半天bfs,发现路径不会标记了,于是发现好像有什么不对的,似乎dfs要简单一点,于是半路跑去打dfs,结果打了半 ...

  6. [USACO5.1]夜空繁星Starry Night

    题目背景 高高的星空,簇簇闪耀的群星形态万千.一个星座(cluster)是一群连通的星组成的非空连通星系,这里的连通是指水平,垂直或者对角相邻的两个星星.一个星座不能是另一个更大星座的一部分, 星座可 ...

  7. HDU5957 Query on a graph(拓扑找环,BFS序,线段树更新,分类讨论)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5957 题意:D(u,v)是节点u和节点v之间的距离,S(u,v)是一系列满足D(u,x)<=k的点 ...

  8. hihocoder#1050 : 树中的最长路(树中最长路算法 两次BFS找根节点求最长+BFS标记路径长度+bfs不容易超时,用dfs做TLE了)

    #1050 : 树中的最长路 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中, ...

  9. POJ-3984 迷宫问题(BFS找最短路径并保存)

    问题: 定义一个二维数组:  int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, ...

随机推荐

  1. 微信打开网址添加在浏览器中打开提示 http://caibaojian.com/weixin-tip.html

    原文链接:http://caibaojian.com/weixin-tip.html#t2 使用微信打开网址时,无法在微信内打开常用下载软件,手机APP等.网上流传的各种微信打开下载链接,微信已更新基 ...

  2. AJPFX关于File类复习

    file是一个路径,分为相对路径(eclipse)和绝对路径:1.构造方法有:File(String pathname ),File(String parent ,String child),File ...

  3. 用idea+maven编译打包spark project core错误:java.lang.RuntimeException: Unable to load a Suite class

    Discovery starting. *** RUN ABORTED *** java.lang.RuntimeException: Unable to load a Suite class tha ...

  4. wget安装更新

    #查看当前wget版本信息 wget -V #下载 wget https://ftp.gnu.org/gnu/wget/wget-1.19.tar.gz #解压 tar xvf wget-1.19.t ...

  5. [小记]Android缓存问题

    今天晚上,产品经理打电话说我们的Android App除了问题,问题很简单就是一个缓存问题,由于这个程序是前同事写的,我也只能呵呵一笑,有些事你就得扛.还是回到正题吧,这个缓存问题,实在有点奇葩,所以 ...

  6. 利用nginx与nginx-rtmp-module搭建流媒体服务器实现直播

    使用环境是centos 7.0+nginx:可以实现简单的流媒体服务. 先下载nginx-rtmp-module拓展: nginx-rtmp-module的官方github地址:https://git ...

  7. 前端phtooshop基础

    1.图片理论基础 2.使用Adobe FireWorks切图和S0VG的处理 可以单独生成一个图片的切图 选择多个切图部分生成CSS  Sprite,甚至CSS和html都生成了对应的文件. 3.Ph ...

  8. laravel 只有/login路由403,如何解决

    链接/login自动转跳到/login/导致找不到 /public/login/ 目录导致403; 将路由中\login改为\login1访问正常,但login依然403,而不是未找到路由 链接/lo ...

  9. windows 下安装 RabbitMQ

    一.安装 RabbitMQ 前需要先安装 Erlang http://www.erlang.org/downloads 下下载对应版本的安装文件进行安装. 安装完成后配置环境变量: ERLANG_HO ...

  10. JS和C#方法相互调用

    JS和C#方法相互调用 1.JS调用C#后台方法 方法一: 1.首先建立一个按钮,在后台将调用或处理的内容写入button_click中;2.在前台写一个js函数,内容为document.getEle ...