HDU ACM 1429 胜利大逃亡(续) (广搜+二进制状态压缩)

http://acm.hdu.edu.cn/showproblem.php?pid=1429

思路:与一般的广搜的的区别是迷宫多了锁,锁的数量最多为10把,用十位表示。所以最大状态为 1K = 1024

  int used[22][22][1100];

  每得到一条钥匙则会转到另一个状态,不同状态的used不会相互干扰。

1 if(map[ans.x][ans.y] >= 'a' && map[ans.x][ans.y] <= 'j'){//标记找到钥匙
2                     ans.key = ans.key | 1<<(map[ans.x][ans.y] - 'a');
3                     used[ans.x][ans.y][ans.key] = 1;
4                     q.push(ans);
5                 }
1 if(map[ans.x][ans.y] >= 'A' && map[ans.x][ans.y] <= 'J'){//判断该锁是否有对应的钥匙
2                         
3                         int x = ans.key>>(map[ans.x][ans.y] - 'A');
4                         if(x & 1){
5                             used[ans.x][ans.y][ans.key] = 1;
6                             q.push(ans);
7                         }
8                     }
 1 #include <iostream>
 2 #include <queue>
 3 using namespace std;
 4 char map[22][22];
 5 int used[22][22][1100];
 6 const int INF = 0x3fffffff;
 7 struct Node{
 8     int x;
 9     int y;
10     int step;
11     int key;
12 };
13 
14 int point[4][2] = {-1,0,1,0,0,-1,0,1};//上 下 左 右
15 int n,m,t;
16 int BFS(Node s,Node e){
17     queue <Node> q;
18     memset(used,0,sizeof(used));
19     q.push(s);
20     used[s.x][s.y][s.key] = 1;
21     while(!q.empty()){
22         Node mid = q.front();
23         q.pop();
24         int i;
25         for(i=0;i<4;i++){
26             Node ans = mid;
27             ans.x = ans.x + point[i][0];
28             ans.y = ans.y + point[i][1];
29             ans.step++;
30             if(ans.x == e.x && ans.y == e.y){
31                 return ans.step;
32             }
33             if(ans.x >= 0 && ans.x <n && ans.y >=0 && ans.y < m
34                 && !used[ans.x][ans.y][ans.key] && map[ans.x][ans.y]!= '*' ){
35 
36                 if(map[ans.x][ans.y] >= 'a' && map[ans.x][ans.y] <= 'j'){//标记找到钥匙
37                     ans.key = ans.key | 1<<(map[ans.x][ans.y] - 'a');
38                     used[ans.x][ans.y][ans.key] = 1;
39                     q.push(ans);
40                 }
41                 else{
42                     if(map[ans.x][ans.y] >= 'A' && map[ans.x][ans.y] <= 'J'){//判断该锁是否有对应的钥匙
43                         
44                         int x = ans.key>>(map[ans.x][ans.y] - 'A');
45                         if(x & 1){
46                             used[ans.x][ans.y][ans.key] = 1;
47                             q.push(ans);
48                         }
49                     }
50                     else{
51                         used[ans.x][ans.y][ans.key] = 1;
52                         q.push(ans);
53                     }
54                 }
55             }
56         }
57     }
58     return INF;
59 }
60 int main(){
61     while(cin>>n>>m>>t){
62         int i,j;
63         Node s = {0};
64         Node e = {0};
65         for(i=0;i<n;i++){
66             for(j=0;j<m;j++){
67                 cin>>map[i][j];
68                 if(map[i][j] == '@'){
69                     s.x = i;
70                     s.y = j;
71                     map[i][j] = '.';
72                 }
73                 if(map[i][j] == '^'){
74                     e.x = i;
75                     e.y = j;
76                 }
77             }
78         }
79         int ans = BFS(s,e);
80         if(ans < t){
81             cout<<ans<<endl;
82         }
83         else{
84             cout<<-1<<endl;
85         }
86     }
87 
88     return 0;
89 }

 

转载于:https://www.cnblogs.com/zxotl/archive/2013/01/22/2871797.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值