HDU 4771 状压bfs

Stealing Harry Potter‘s Precious

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1295    Accepted Submission(s): 618

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

题目意思:

给一个n*m的迷宫,给一个k,下面k行为x, y。  一个人从@处开始走,只能上下左右走,走一步时间+1,#为墙,问人能否走遍给出的k个x,y。

若能输出最小步数,否则输出-1.

思路:

该题难点在于怎么判断一个人是否遍历k所有的x,y。   而且不同的路径已经经过的x,y也不同。若在每个路径中存放一个地图,那么很容易超时,由于k最大为4,所有对k个坐标状压即可。

代码:

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <vector>
  6 #include <queue>
  7 using namespace std;
  8
  9 #define N 105
 10
 11 char map[N][N];
 12 int visited[N][N][1<<4];
 13 int n, m, k;
 14 int xx[]={1,-1,0,0};
 15 int yy[]={0,0,1,-1};
 16
 17 struct node{
 18     int x, y, pr, t;
 19 };
 20
 21 int bfs(int stx,int sty){
 22     memset(visited,0,sizeof(visited));
 23     node p, q;
 24     int i, j;
 25     queue<node>Q;
 26     p.x=stx;p.y=sty;p.pr=0;p.t=0;
 27     visited[p.x][p.y][p.pr]=1;
 28     Q.push(p);
 29     while(!Q.empty()){
 30          p=Q.front();
 31          Q.pop();
 32          if(p.pr==(1<<k)-1) return p.t;         //当遍历完k个坐标就return
 33
 34          for(i=0;i<4;i++){
 35              p.x+=xx[i];
 36              p.y+=yy[i];
 37              if(p.x>=0&&p.x<n&&p.y>=0&&p.y<m&&map[p.x][p.y]!=‘#‘&&!visited[p.x][p.y][p.pr]){
 38                  visited[p.x][p.y][p.pr]=1;
 39                  if(map[p.x][p.y]!=‘.‘){     //当走到给的k个坐标处
 40                      if(p.pr&(1<<(map[p.x][p.y]-‘0‘))){   //已经走过该坐标
 41                          p.t+=1;
 42                          Q.push(p);
 43                          p.t-=1;
 44                      }
 45                      else{                //没走过该坐标
 46                          int u=p.pr;
 47                          p.pr=p.pr|(1<<(map[p.x][p.y]-‘0‘));
 48                          p.t+=1;
 49                          visited[p.x][p.y][p.pr]=1;
 50                          Q.push(p);
 51                          p.t-=1;
 52                          p.pr=u;
 53                      }
 54                  }
 55                  else{
 56                      p.t+=1;
 57                      Q.push(p);
 58                      p.t-=1;
 59                  }
 60              }
 61              p.x-=xx[i];
 62              p.y-=yy[i];
 63          }
 64
 65     }
 66     return -1;
 67 }
 68
 69 main()
 70 {
 71      int i, j, x, y;
 72      while(scanf("%d %d",&n,&m)==2){
 73          if(!n&&!m) break;
 74          for(i=0;i<n;i++) scanf("%s",map[i]);
 75          int stx, sty, f=0;
 76          for(i=0;i<n;i++){
 77              for(j=0;j<m;j++){
 78                  if(map[i][j]==‘@‘){
 79                      stx=i;sty=j;f=1;break;
 80                  }
 81              }if(f) break;
 82          }
 83          scanf("%d",&k);
 84           f=0;int cnt=0, ka=k;
 85          while(ka--){
 86              scanf("%d %d",&x,&y);
 87              x--;y--;
 88              if(f) continue;
 89              if(map[x][y]==‘#‘){     //若给的坐标处为墙,肯定没法遍历完k个坐标
 90                  f=1;
 91              }
 92              else{
 93                  map[x][y]=cnt+‘0‘;
 94                  cnt++;
 95              }
 96          }
 97          if(f) {
 98              printf("-1\n");continue;
 99          }
100          int ans=bfs(stx,sty);
101          if(ans!=-1) printf("%d\n",ans);
102          else printf("-1\n");
103      }
104 }
时间: 2024-10-28 11:28:19

HDU 4771 状压bfs的相关文章

hdu 1429 状压bfs

#include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #define inf 0x3f3f3f3f #define ll __in

HDU 5094 状压BFS

给出n*m矩阵 给出k个障碍,两坐标之间存在墙或门,门最多10种, 给出s个钥匙位置及编号,相应的钥匙开相应的门 状压BFS即可,注意有可能同一个位置有多个门或者多个钥匙 #include "stdio.h" #include "string.h" #include "queue" using namespace std; int b[]={1,2,4,8,16,32,64,128,256,512,1024,2048}; int dir[4][2

hdu 4845 状压bfs(分层思想)

拯救大兵瑞恩 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 255    Accepted Submission(s): 99 Problem Description 1944年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩.瑞恩被关押在一个迷宫里,迷宫地形复杂,但是幸好麦克得到了迷宫的地形图.

HDU 4012 Paint on a Wall(状压+bfs)

Paint on a Wall Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Submission(s): 830    Accepted Submission(s): 325 Problem Description Annie wants to paint her wall to an expected pattern. The wall can be repr

HDU 4284 状压dp+spfa堆优化

题意: 给定n个点 m条无向边 d元. 下面m行表示每条边 u<=>v 以及花费 w 下面top 下面top行 num c d 表示点标为num的城市 工资为c 健康证价格为d 目标是经过给定的top个城市,当到达该城市时,必须马上购买该城市的健康证并打工赚钱(每个城市只打工1次) 问从1城市出发,最后回到1城市,能否收集到所有的健康证 思路: 由于top很小,所以状压dp dp[i][tmp]表示当前处于i点 经过城市的状态为tmp时 身上最多的钱. 首先对dis数组floyd 跑出最短路,

hdu 4906 状压dp

/* ID: neverchanje PROG: LANG: C++11 */ #include<vector> #include<iostream> #include<cstring> #include<string> #include<algorithm> #include<cmath> #include<cstdio> #include<set> #include<queue> #includ

HDU 4892 状压dp

[BestCoder Round #5]冠军的奖励是小米3手机一部 恭喜福州大学杨楠获得[BestCoder Round #4]冠军(iPad Mini一部) <BestCoder用户手册>下载 Defence of the Trees Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 224    Accepted Submiss

[GDOI2015]推箱子(状压bfs)

[GDOI2015]推箱子(状压bfs) 题面 题面过长,略 分析 观察到$m \times m =64 \(,那么可以把箱子的01状态压到一个```unsigned long long```里面 然后对于地图上的每一个点\)(x,y)\(,预处理出左上角在\)(x,y)\(,边长为\)m\(的正方形的01状态.如果这个状态和箱子的状态按位与的结果为0,那么就说明箱子可以通过. 然后发现这类似一个分层图上的最短路问题,直接BFS即可.状态\)dist[x][y][k]\(表示箱子左上角在\)(x

HDU 3619 优先队列+状压+bfs

Heroes of Might and Magic Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 170    Accepted Submission(s): 74 Problem Description After a very long journey and uncountable number of uphill battles