hdu2128之BFS
Tempter of the Bone II
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 98304/32768 K (Java/Others)
Total Submission(s): 1090 Accepted Submission(s): 272
The maze was a rectangle with the sizes of N by M. The maze is made up of a door,many walls and many explosives. Doggie need to reach the door to escape from the tempter. In every second, he could move one block to one of the upper, lower, left or right neighboring blocks. And if the destination is a wall, Doggie need another second explode and a explosive to explode it if he had some explosives. Once he entered a block with explosives,he can take away all of the explosives. Can the poor doggie survive? Please help him.
'X': a block of wall;
'S': the start point of the doggie;
'D': the Door;
'.': an empty block;
'1'--'9':explosives in that block.
Note,initially he had no explosives.
The input is terminated with two 0's. This test case is not to be processed.
SX..
XX..
....
1..D
4 4
S.X1
....
..XX
..XD
0 0
9
分析:由题目可以得到这样一个状态:在某点(x,y)含有炸弹数num且炸毁过哪些墙(实际上我是错了几次才完事这个状态的)
如这组数据:
6 5
S.XX1
X.1X1
XX.X.
XXXXX
XXXXX
XXXDX
在(1,4)这个点含有炸弹数量为1的状态就有2种:1是炸墙(1,3)过去的,2事炸墙(2,3)过去的,不同的状态会导致不同的结果
所以用:vector<long long int>mark[MAX][MAX][MAX*MAX*9];//在i,j含有炸弹k时所炸过的墙,来记录,至于炸过的墙和拿过的炸弹(拿过了就不能再拿了,所以也要记录),在这里我用状态压缩来记录,用数的二进制表示中德0,1来表示否还是是,由于8*8的网格,恰好unsigned long long int 能表示
这题就是分析某点的状态和记录比较麻烦,其他都和一般的搜索一样
给几组数据:
6 5
S.XX1
X.1X1
XX.X.
XXXXX
XXXXX
XXXDX
2 6
S.1XXD
1..XXX
4 4
S1X1
XXXX
XXDX
XXXX
6 2
S1
..
1X
XX
XX
DX
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<vector>
#include<iomanip>
#define INF 99999999
using namespace std; const int MAX=8+10;
vector<long long int>mark[MAX][MAX][MAX*MAX*9];//在i,j含有炸弹k时所炸过的墙
char Map[MAX][MAX];
int n,m;
int dir[4][2]={0,1,0,-1,1,0,-1,0}; struct Node{
int x,y,num,time;
unsigned long long open;//表示已经炸过的墙(最多8*8位)
unsigned long long key;//表示已经取过的炸药位置(最多8*8)
Node(){}
Node(int X,int Y,int Num,int Time,unsigned long long Open,unsigned long long Key){
x=X,y=Y,num=Num;
time=Time,open=Open,key=Key;
}
bool operator<(Node const &a)const{
return time>a.time;
}
}start; bool check(Node &next){
int size=mark[next.x][next.y][next.num].size();
for(int i=0;i<size;++i){//判断在该位置拥有炸弹num的情况下炸过的墙是否一样
if(next.open == mark[next.x][next.y][next.num][i])return true;
}
return false;
} int BFS(){
priority_queue<Node>q;
Node oq,next;
q.push(start);
while(!q.empty()){
oq=q.top();
q.pop();
for(int i=0;i<4;++i){
next=Node(oq.x+dir[i][0],oq.y+dir[i][1],oq.num,oq.time+1,oq.open,oq.key);
if(next.x<0 || next.y<0 || next.x>=n || next.y>=m)continue;
if(Map[next.x][next.y] == 'X'){//该点是墙
int k=next.x*m+next.y;
if( !((next.open>>k)&1) )--next.num,++next.time;//是否已炸过
next.open|=((1ll)<<k);
}
if(Map[next.x][next.y]>='1' && Map[next.x][next.y]<='9'){//该点有炸药可取
int k=next.x*m+next.y;
if( !((next.key>>k)&1) )next.num+=Map[next.x][next.y]-'0';//是否已取过
next.key|=((1ll)<<k);
}
if(next.num<0 || check(next))continue;
mark[next.x][next.y][next.num].push_back(next.open);
if(Map[next.x][next.y] == 'D')return next.time;
q.push(next);
}
}
return -1;
} void Init(){
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
for(int k=0;k<=m*n*9;++k){
mark[i][j][k].clear();//初始化没炸过任何墙
}
}
}
} int main(){
while(cin>>n>>m,n+m){
Init();
memset(mark,-1,sizeof mark);
for(int i=0;i<n;++i)cin>>Map[i];
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
if(Map[i][j] == 'S')start=Node(i,j,0,0,0,0);
}
}
cout<<BFS()<<endl;
}
return 0;
}
hdu2128之BFS的更多相关文章
- 图的遍历(搜索)算法(深度优先算法DFS和广度优先算法BFS)
图的遍历的定义: 从图的某个顶点出发访问遍图中所有顶点,且每个顶点仅被访问一次.(连通图与非连通图) 深度优先遍历(DFS): 1.访问指定的起始顶点: 2.若当前访问的顶点的邻接顶点有未被访问的,则 ...
- 【BZOJ-1656】The Grove 树木 BFS + 射线法
1656: [Usaco2006 Jan] The Grove 树木 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 186 Solved: 118[Su ...
- POJ 3278 Catch That Cow(bfs)
传送门 Catch That Cow Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 80273 Accepted: 25 ...
- POJ 2251 Dungeon Master(3D迷宫 bfs)
传送门 Dungeon Master Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 28416 Accepted: 11 ...
- Sicily 1215: 脱离地牢(BFS)
这道题按照题意直接BFS即可,主要要注意题意中的相遇是指两种情况:一种是同时到达同一格子,另一种是在移动时相遇,如Paris在(1,2),而Helen在(1,2),若下一步Paris到达(1,1),而 ...
- Sicily 1048: Inverso(BFS)
题意是给出一个3*3的黑白网格,每点击其中一格就会使某些格子的颜色发生转变,求达到目标状态网格的操作.可用BFS搜索解答,用vector储存每次的操作 #include<bits/stdc++. ...
- Sicily 1444: Prime Path(BFS)
题意为给出两个四位素数A.B,每次只能对A的某一位数字进行修改,使它成为另一个四位的素数,问最少经过多少操作,能使A变到B.可以直接进行BFS搜索 #include<bits/stdc++.h& ...
- Sicily 1051: 魔板(BFS+排重)
相对1150题来说,这道题的N可能超过10,所以需要进行排重,即相同状态的魔板不要重复压倒队列里,这里我用map储存操作过的状态,也可以用康托编码来储存状态,这样时间缩短为0.03秒.关于康托展开可以 ...
- Sicily 1150: 简单魔板(BFS)
此题可以使用BFS进行解答,使用8位的十进制数来储存魔板的状态,用BFS进行搜索即可 #include <bits/stdc++.h> using namespace std; int o ...
随机推荐
- Shell脚本——中继DHCP服务器自动部署
详细说明参照: (四)跟我一起玩Linux网络服务:DHCP服务配置之中继代理 vm1的脚本是: #! /bin/bash HIPSEG="10.10.10" SIPSEG=&qu ...
- 异步调用backgroudworker
先看一个小例子:C#客户端打开一个控件,控件中加载了好多数据大约要用5秒中,如果我们直接打开控件,那么这个控件就要5秒中才能弹出来,当然这个时候用户已经把他Kill了.这个时候我们就需要先给用户把控件 ...
- 生产环境CentOS服务器系统安全配置
转http://www.centoscn.com/CentosSecurity/CentosSafe/2014/1126/4192.html 账户安全及权限 禁用root以外的超级用户 删除不必要的账 ...
- 开启g++ 编辑器 c++11特性
以前都是在windows下用vs和cvi写C和C++代码,最近练习Linux下的使用. 编译的时候使用C++11的新特性比如auto 和 iteration特性都报不支持,后来在知乎看到答案需要在编译 ...
- C++11老关键字的新含义(auto, using,extern)
http://blog.csdn.net/cnsword/article/details/8034947 公司可以使用c++11.看大牛的代码模仿使用,所以现在已经不知道什么使用的是c++的语法还是c ...
- IntelIoT技术笔记Java/Eclipse
1. 获取最新版本 使用"Team sync perspective",如果想要看到全部工程的差异,选择全部工程,右键-Team-sync with Repository:将会自动 ...
- NET平台和C#
.NET平台和C#编程 一.深入.NET框架 1..NET框架具有两个组件:CLR(公共语言运行时)和FCL(框架类库),CLR是.NET框架的基础 2.框架核心类库: System.Collecti ...
- 关于Kingfisher--备用
序言--感谢好心大神分享 Kingfisher 是由 @onevcat 编写的用于下载和缓存网络图片的轻量级Swift工具库,其中涉及到了包括GCD.Swift高级语法.缓存.硬盘读写.网络编程.图像 ...
- Quartz1.8.5例子(三)
/* * Copyright 2005 - 2009 Terracotta, Inc. * * Licensed under the Apache License, Version 2.0 (the ...
- php版的求表达式的真值表-TrueValueTable
贴上代码: <?php error_reporting(E_ALL & ~E_NOTICE); $expression=$_GET['TrueTable']; //读取输入框数据 if( ...