hdu 4774 Stealing Harry Potter's Precious 状态压缩+bfs 解题报告
2016-07-10 17:19
381 查看
Stealing Harry Potter's Precious
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3065 Accepted Submission(s): 1374
Problem Description
Harry Potter has some precious. For example, his invisible robe, his wand and his owl. When Hogwarts school is in holiday, Harry Potter has to go back to uncle Vernon's home. But he can't bring his precious with him. As you know, uncle Vernon never allows
such magic things in his house. So Harry has to deposit his precious in the Gringotts Wizarding Bank which is owned by some goblins. The bank can be considered as a N × M grid consisting of N × M rooms. Each room has a coordinate. The coordinates of the upper-left
room is (1,1) , the down-right room is (N,M) and the room below the upper-left room is (2,1)..... A 3×4 bank grid is shown below:
Some rooms are indestructible and some rooms are vulnerable. Goblins always care more about their own safety than their customers' properties, so they live in the indestructible rooms and put customers' properties in vulnerable rooms. Harry Potter's precious
are also put in some vulnerable rooms. Dudely wants to steal Harry's things this holiday. He gets the most advanced drilling machine from his father, uncle Vernon, and drills into the bank. But he can only pass though the vulnerable rooms. He can't access
the indestructible rooms. He starts from a certain vulnerable room, and then moves in four directions: north, east, south and west. Dudely knows where Harry's precious are. He wants to collect all Harry's precious by as less steps as possible. Moving from
one room to another adjacent room is called a 'step'. Dudely doesn't want to get out of the bank before he collects all Harry's things. Dudely is stupid.He pay you $1,000,000 to figure out at least how many steps he must take to get all Harry's precious.
Input
There are several test cases.
In each test cases:
The first line are two integers N and M, meaning that the bank is a N × M grid(0<N,M <= 100).
Then a N×M matrix follows. Each element is a letter standing for a room. '#' means a indestructible room, '.' means a vulnerable room, and the only '@' means the vulnerable room from which Dudely starts to move.
The next line is an integer K ( 0 < K <= 4), indicating there are K Harry Potter's precious in the bank.
In next K lines, each line describes the position of a Harry Potter's precious by two integers X and Y, meaning that there is a precious in room (X,Y).
The input ends with N = 0 and M = 0
Output
For each test case, print the minimum number of steps Dudely must take. If Dudely can't get all Harry's things, print -1.
Sample Input
2 3
##@
#.#
1
2 2
4 4
#@##
....
####
....
2
2 1
2 4
0 0
Sample Output
-1
5
思路:用二进制保存状态,然后bfs
代码:
#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
#define MAXN 100 + 10
struct node
{
int x, y, now, step;
} w[5], p, q;
node xin ,tou;
int vis[1<<4][MAXN][MAXN];
int map[MAXN][MAXN];
int fx[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
int n ,m ,k, sx, sy;
int bfs()
{
queue<node>Q;
p.x = sx;
p.y = sy;
p.now = 0;
p.step = 0;
//看起始点是不是已经有宝藏了
int index = 0;
for(int i = 1 ; i <= k ; i ++)
if(xin.x == w[i].x && xin.y == w[i].y)
{
index = i;
break;
}
if(index) p.now = 0 | (1 << (index - 1));
vis[p.now][p.x][p.y] = 1;
Q.push(p);
while(!Q.empty())
{
p = Q.front();
Q.pop();
if(p.now == (1<<k) - 1)
return p.step;
for(int i = 0; i < 4; i++)
{
q.x = p.x + fx[i][0];
q.y = p.y + fx[i][1];
q.step = p.step + 1;
index = 0;
for(int j = 1 ; j <= k ; j ++)
if(q.x == w[j].x && q.y == w[j].y)
{
index = j;
break;
}
if(index) q.now = p.now | (1 << (index - 1));
else q.now = p.now;
if(!vis[q.now][q.x][q.y] && q.x >= 1 && q.y >= 1 && q.x <= n && q.y <= m && map[q.x][q.y] != 0)
{
vis[q.now][q.x][q.y] = 1;
Q.push(q);
}
}
}
return -1;
}
int main ()
{
char str[MAXN];
while(scanf("%d %d" ,&n ,&m), n, m)
{
memset(vis ,0 ,sizeof(vis));
for(int i = 1; i <= n; i++)
{
scanf("%s" ,str);
for(int j = 1; j <= m; j++)
{
if(str[j-1] == '@')
map[i][j] = 1, sx = i, sy = j;
if(str[j-1] == '.')
map[i][j] = 1;
if(str[j-1] == '#')
map[i][j] = 0;
}
}
scanf("%d" ,&k);
for(int i = 1 ; i <= k ; i ++)
scanf("%d %d" ,&w[i].x ,&w[i].y);
printf("%d\n" ,bfs());
}
return 0;
}
相关文章推荐
- 搜狗百度360市值齐跌:搜索引擎们陷入集体焦虑?
- 本人即将筹备败家日志,敬请期待!
- IE:使用搜索助手
- C++深度优先搜索的实现方法
- 基于文本的搜索
- php实现搜索一维数组元素并删除二维数组对应元素的方法
- 使用Sphinx对索引进行搜索
- asp 多关键词搜索的简单实现方法
- C#使用foreach语句搜索数组元素的方法
- WordPress中用于获取搜索表单的PHP函数使用解析
- JavaScript中数组的排序、乱序和搜索实现代码
- jquery ztree实现树的搜索功能
- 【经典源码收藏】jQuery实用代码片段(筛选,搜索,样式,清除默认值,多选等)
- C#编程实现Excel文档中搜索文本内容的方法及思路
- sqlserver中在指定数据库的所有表的所有列中搜索给定的值
- 可以用来搜索当前页面内容的js代码
- 全文搜索和替换
- javascript搜索自动提示功能的实现第1/3页
- iOS应用中UISearchDisplayController搜索效果的用法
- mysql 模糊搜索的方法介绍