蓝桥杯系列 - 2018国赛 - 迷宫与陷阱

BFS题,大致遵循以下思路:

  1. 可以设置一个结构体,包含 4 个成员: x, y, step, state。其中 x, y 表示当前处在迷宫中的位置,step 表示到达该位置时总共用了多少步,state 表示无敌状态剩余的步数,state = 0 表示非无敌状态,state > 0 表示处于无敌状态,每走一步就减 1。
  2. 设置 vis[n][n] 数组, vis[i][j] 记录迷宫位置 i, j 是否被访问过。
  3. 假设迷宫用 maze[n][n] 表示,当前位置为 curx, cury,当前步数为 step,无敌状态剩余步数为 state。假设下一步位置为 nextx, nexty,按照以下顺序进行判断:
    3.1. 如果 nextx, nexty 越界了,或者 maze[n][n] == ‘#’,跳过位置 nextx, nexty;
    3.2. 否则,如果 vis[next][nexty] != 0 (未被访问),见 Pseudocode1 说明;
    3.3. 否则,见 Pseudocode2 说明。
  4. 当到达 n, n 时,直接返回到达 n, n 的步数即可,由于 BFS 的辐射状搜索的特点,可以保证此时肯定是到达 n, n 的最少步数,如果到达不了 n, n 就返回 -1 。
""" Pseudocode1 """
if maze[nextx][nexty] == '.':
	将位置 (nextx, nexty, step + 1, 0 或 state - 1) 添加进 BFS 队列
	vis[nextx][nexty] = True
else if maze[nextx][nexty] == 'X':
	// 陷阱只有无敌状态时才能通过, 所以要检查 state 是否为 0
	if state > 0:
		将位置 (nextx, nexty, step + 1, state - 1) 添加进 BFS 队列
		vis[nextx][nexty] = True
else if maze[nextx][nexty] == '%':
	将位置 (nextx, nexty, step + 1, K) 添加进 BFS 队列, K 的意义与题目提供的一致
	vis[nextx][nexty] = True
""" Pseudocode2 """
if (maze[nextx][nexty] == '.' or maze[nextx][nexty] == 'X') and state > 0:
	// state > 0 表示当前正处于无敌状态,无敌状态不受 vis 的影响,只要不是 '#''%' 就随便走
	将位置 (nextx, nexty, step + 1, state - 1) 添加进 BFS 队列

Python 代码:

import sys

from collections import deque


def BFS(n, k, mz):
    dirs = [(1, 0), (0, 1), (-1, 0), (0, -1)]
    vis = [[False for _ in range(n)] for __ in range(n)]
    queue = deque()

    endx, endy = n - 1, n - 1
    vis[0][0] = True
    queue.append((0, 0, 0, 0))
    while queue:
        curx, cury, step, state = queue.popleft()
        if curx == endx and cury == endy:
            return step
        for i in range(4):
            nextx, nexty = curx + dirs[i][0], cury + dirs[i][1]
            if nextx < 0 or nextx >= n or nexty < 0 or nexty >= n or mz[nextx][nexty] == '#':
                continue
            elif not vis[nextx][nexty]:
                if mz[nextx][nexty] == '.':
                    queue.append((nextx, nexty, step + 1, state - 1 if state else 0))
                    vis[nextx][nexty] = True
                elif mz[nextx][nexty] == 'X' and state:
                    queue.append((nextx, nexty, step + 1, state - 1))
                    vis[nextx][nexty] = True
                else:
                    queue.append((nextx, nexty, step + 1, k))
                    vis[nextx][nexty] = True
            elif (mz[nextx][nexty] == '.' or mz[nextx][nexty] == 'X') and state:
                queue.append((nextx, nexty, step + 1, state - 1))
    return -1


N, K = list(map(int, sys.stdin.readline().strip().split()))
maze = []
for i in range(N):
    maze.append(sys.stdin.readline().strip())
print(BFS(N, K, maze))

C++ 代码:

#include<cstdio> 
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 1e3 + 5;
int dirs[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
char maze[maxn][maxn];
bool vis[maxn][maxn];
struct block{
	int x;
	int y;
	int step;
	int state;
	
	block(int x, int y, int step, int state){
		this->x = x;
		this->y = y;
		this->step = step;
		this->state = state;
	}
};

int BFS(int n, int k){
	memset(vis, 0, sizeof(vis));
	queue<block> Q;
	
	vis[1][1] = true;
	Q.push(block(1, 1, 0, 0));
	while(!Q.empty()){
		block b = Q.front(); Q.pop();
		int x = b.x, y = b.y, step = b.step, state = b.state;
		if(x == n && y == n)
			return step;
		for(int i = 0; i < 4; ++i){
			int newx = x + dirs[i][0], newy = y + dirs[i][1];
			if(newx < 1 || newx > n || newy < 1 || newy > n)
				continue;
			if(maze[newx][newy] == '#')
				continue;
			else if(!vis[newx][newy]){
				if(maze[newx][newy] == '.'){
					if(state)
						Q.push(block(newx, newy, step + 1, state - 1));
					else
						Q.push(block(newx, newy, step + 1, 0));
					vis[newx][newy] = true;
				}
				else if(maze[newx][newy] == 'X'){
					if(state){
						Q.push(block(newx, newy, step + 1, state - 1));
						vis[newx][newy] = true;
					}
				}
				else{
					Q.push(block(newx, newy, step + 1, k));
					vis[newx][newy] = true;
				}
			}
			else if((maze[newx][newy] == '.' || maze[newx][newy] == 'X') && state){
				Q.push(block(newx, newy, step + 1, state - 1));
			}
		}
	}
	return -1;
}


int main(){
	int n, k;
	scanf("%d%d", &n, &k);
	for(int i = 1; i <= n; ++i){
		scanf("%s", maze[i] + 1);
	}
	printf("%d\n", BFS(n, k));
	return 0;
}

Python 超时,C++ 秒过。Python 果然还是太慢了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值