hdu2128之BFS
来源:互联网 发布:wordpress主题 知乎 编辑:程序博客网 时间:2024/05/16 08:57
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
Problem Description
The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze was changed and the way he came in was lost.He realized that the bone was a trap, and he tried desperately to get out of this maze.
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.
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.
Input
The input consists of multiple test cases. The first line of each test case contains two integers N, M,(2 <= N, M <= 8). which denote the sizes of the maze.The next N lines give the maze layout, with each line containing M characters. A character is one of the following:
'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.
'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.
Output
For each test case, print the minimum time the doggie need to escape if the doggie can survive, or -1 otherwise.
Sample Input
4 4SX..XX......1..D4 4S.X1......XX..XD0 0
Sample Output
-19
如这组数据:
6 5S.XX1X.1X1XX.X.XXXXXXXXXXXXXDX在(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 5S.XX1X.1X1XX.X.XXXXXXXXXXXXXDX2 6S.1XXD1..XXX4 4S1X1XXXXXXDXXXXX6 2S1..1XXXXXDX
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<map>#include<vector>#include<iomanip>#define INF 99999999using 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
- hdu2128 Tempter of the Bone II (BFS)
- HDU2128 Tempter of the Bone II BFS
- 【BFS】魔鬼之城
- hdu1429之BFS
- hdu2531之BFS
- hdu2653之BFS
- hdu2579之BFS
- hdu2364之BFS
- hdu2216之BFS
- hdu1547之BFS
- hdu2102之BFS
- hdu4308之BFS
- hdu2757之BFS
- 算法入门之BFS
- 搜索专题之BFS
- 实现BFS之“营救”
- hdu4460之BFS
- linux的date的几个例子
- 关于Java交换两个对象的问题
- 第三章数程序设计初步--控制结构综合项目4-2文件操作初体验练习4将数据写入文件
- Boot Camp 支持软件与系统要求对照表——用于手工下载Window 支持软件(驱动)
- IOS音频播放概述
- hdu2128之BFS
- 文本框下拉提示效果(模拟百度效果提示框)
- ===《C/C++笔记》===指针
- C++一些注意点之操作符重载
- word跨页的表格默认增加上表头
- android开发中常用的快捷键
- Android linux的休眠和唤醒
- oracle sql优化 二 (转载)
- atlcom.h(2945) : error C2065: '_Module' : undeclared identifier