openjudge2.5基本算法之搜索——1159:Maze

文章讲述了Acm在特殊迷宫中的寻宝过程,需要找到所有门的钥匙才能打开通往宝藏的门。通过广度优先搜索算法判断Acm能否找到宝藏。

题目

`1159:Maze
描述
Acm, a treasure-explorer, is exploring again. This time he is in a special maze, in which there are some doors (at most 5 doors, represented by ‘A’, ‘B’, ‘C’, ‘D’, ‘E’ respectively). In order to find the treasure, Acm may need to open doors. However, to open a door he needs to find all the door’s keys (at least one) in the maze first. For example, if there are 3 keys of Door A, to open the door he should find all the 3 keys first (that’s three 'a’s which denote the keys of ‘A’ in the maze). Now make a program to tell Acm whether he can find the treasure or not. Notice that Acm can only go up, down, left and right in the maze.
输入
The input consists of multiple test cases. The first line of each test case contains two integers M and N (1 < N, M < 20), which denote the size of the maze. The next M lines give the maze layout, with each line containing N characters. A character is one of the following: ‘X’ (a block of wall,

### 关于OpenJudge 2.5 题目的解题思路 #### The Castle (ybt 1250) 对于城堡问题,核心在于理解如何通过二进制表示墙壁的存在情况并利用搜索算法遍历连通区域。每个房间可以用一个整数描述其四面墙的状态,其中每一位代表一面墙是否存在。例如,北墙对应最低位,东墙次之,南墙再次,西墙最高位[^1]。 ```cpp #include <iostream> using namespace std; int main() { int w, h; cin >> w >> h; vector<vector<int>> room(h + 2, vector<int>(w + 2)); for(int i = 1; i <= h; ++i){ for(int j = 1; j <= w; ++j){ cin >> room[i][j]; } } // 定义方向数组用于移动 const int dx[] = {0, -1, 0, 1}; const int dy[] = {-1, 0, 1, 0}; function<void(int,int)> dfs = [&](int x, int y){ if(x < 1 || x > h || y < 1 || y > w) return; int walls = room[x][y]; room[x][y] |= 8; // 标记已访问 for(int d = 0; d < 4; ++d){ if((walls & (1 << ((d+2)%4))) == 0){ // 如果该方向无墙,则继续探索 dfs(x + dx[d], y + dy[d]); } } }; int areaCount = 0; for(int i = 1; i <= h; ++i){ for(int j = 1; j <= w; ++j){ if(room[i][j] < 8){ dfs(i, j); ++areaCount; } } } cout << "Number of rooms: " << areaCount << endl; } ``` 此代码实现了深度优先搜索(DFS),用来计算不相连的房间数量。当遇到未被标记过的房间时启动一次新的DFS过程,并增加计数值。 #### Maze with Doors and Keys (OpenJudge NOI 2.5 1159) 针对带有门和钥匙的迷宫问题,解决方案涉及广度优先搜索(BFS)配合状态记录机制。由于存在多个可能影响路径的关键因素——即不同种类的门及其对应的钥匙,因此需要设计一种方式来追踪当前持有的钥匙集合以及已经解锁过哪些类型的门。可以采用队列存储节点信息的同时也保存这些额外的状态数据[^5]。 ```python from collections import deque def bfs(maze, start_pos): queue = deque([(start_pos, set())]) visited = {(start_pos, frozenset()): False} while queue: pos, keys = queue.popleft() r, c = pos # 边界条件检查... cell = maze[r][c] new_keys = keys.copy() if 'a' <= cell <= 'e': new_keys.add(cell.upper()) elif 'A' <= cell <= 'E' and cell not in keys: continue next_positions = [ (r-1,c), (r+1,c), (r,c-1), (r,c+1) ] for nr, nc in next_positions: if is_valid(nr,nc,maze): state = (nr, nc), frozenset(new_keys) if state not in visited or not visited[state]: visited[state] = True queue.append(((nr, nc), new_keys)) return all_doors_opened(keys) maze = [] for _ in range(rows): row_input = input().strip() maze.append(list(row_input)) print(bfs(maze, initial_position)) ``` 这段Python脚本展示了基本框架,实际应用中还需要补充边界验证逻辑(`is_valid`)和其他细节处理函数。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值