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 ...
随机推荐
- 发现一款移动web端远程调试工具weinre , 哈哈!
之前调试一直用的是chrome的远程调试,虽然效果很不错,但是在调试cordova,微信时多有不便. 在git上找工具时发现了这个:weinre,使用方法非常简单 附上git地址: https://g ...
- PHP开发APP接口---返回数据的封装类
参考视频http://www.imooc.com/learn/163 <?php /** * app返回数据类 * 1.接受多维,缺少键名的数组, * 2.可由输入的format参数决定返回数据 ...
- POJ 1013 Counterfeit Dollar 集合上的位运算
Description Sally Jones has a dozen Voyageur silver dollars. However, only eleven of the coins are t ...
- bzoj2011: [Ceoi2010]Mp3 Player
Description Georg有个MP3 Player,没有任何操作T秒钟就会锁定,这时按下任意一个键就会变回没锁定的状态,但不会改变频道.只有在没锁定的状态下按键才有可能改变频道. MP3的频道 ...
- BZOJ 2005 能量采集
Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后,栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起. 栋栋的植物种得 ...
- 浅谈C# .Net技术面试 , 正在找工作的人一定要看看
1.引子 最近一直在负责.net(B/S方向)技术面试相关的工作,前前后后面试了不少人,但是通过率较低,大概只有20%左右:有颇多感慨. 最近也一直比较困惑,原因究竟是什么? 是我们要求太高,应聘者本 ...
- indexedDB article
http://www.html5china.com/HTML5features/LocalStorage/20110926_2022.html http://www.cnblogs.com/haner ...
- python处理csv数据
import csv #从文件读取 reader = csv.reader(file(srcFilePath,'rb')) for line in reader: #忽略第一行 if reader.l ...
- codeforces D. Count Good Substrings
http://codeforces.com/contest/451/problem/D 题意:给你一个字符串,然后找出奇数和偶数长度的子串的个数,这些字串符合,通过一些连续相同的字符合并后是回文串. ...
- jsp的url后跟中文参数传参出现乱码
①重新编码:String urlParam= request.getParameter("urlParam"); urlParam= new String(urlParam.ge ...