【BFS题型二/四维坐标]打开转盘锁

752. 打开转盘锁

1.四位密码也就相当于四维坐标迷宫

2.给出的危险密码也就是障碍物

3.该坐标系有范围,大小是0~9

4.开辟多余的维度存储步数

6.定义所有坐标是否走过的状态vid列表

5.注意灵活运用

s=''.join(list(map(str, new[:4])))  将整型列表转换为字符串

sl=list(s)将字符串转换为列表

end=list(map(int, sl))      将列表的元素类型转换成整型  

6.注意特殊情况,只要初始位置0000出现在危险密码中就不可能完成,返回-1

7.如果不是从break返回,而是while中断返回的就是未能到达密码,定义条件参数p然后判断是否返回-1或是步长news[4](这里注意不是new[4])

8.对news进行拷贝,在不影响news的情况下对new进行修改(一般的=只是映射关系,地址都一样,一变都变)

class Solution:
    def openLock(self, deadends: List[str], target: str) -> int:   
        start = [0, 0, 0, 0, 0]
        end = list(map(int, list(target)))
        vid = [[[[0] * 10 for i in range(10)] for j in range(10)] for k in range(10)]

        if '0000' in deadends:
            return -1
        def bfs(s, end):
            q = deque()
            q.append(s)
            vid[s[0]][s[1]][s[2]][s[3]] = 1
            p=0
            while q:
                news = q.popleft()
                if news[0] == end[0] and news[1] == end[1] and news[2] == end[2] and news[3] == end[3]:
                    p=1
                    break
                for i in range(4):
                    new = []
                    for j in news:
                        new.append(j)
                    new[i] += 1
                    if new[i] == 10:
                        new[i] = 0
                    if ''.join(list(map(str, new[:4]))) not in deadends and vid[new[0]][new[1]][new[2]][new[3]] != 1:
                        vid[new[0]][new[1]][new[2]][new[3]] = 1
                        new[4] += 1
                        q.append(new)
                        #print(new)
                for i in range(4):
                    new = []
                    for j in news:
                        new.append(j)
                    new[i] -= 1
                    if new[i] == -1:
                        new[i] = 9
                    if ''.join(list(map(str, new[:4]))) not in deadends and vid[new[0]][new[1]][new[2]][new[3]] != 1:
                        vid[new[0]][new[1]][new[2]][new[3]] = 1
                        new[4] += 1
                        q.append(new)
                        #print(new)
            if p==1:
                return news[4]
            return -1
        return bfs(start, end)

密码锁,可相邻旋转的(左右密码可交换位置)

from queue import Queue
q=Queue()
qs=list(map(int,input()))
zd=list(map(int,input()))

vis=[[[[0]*10 for i in range(10)] for j in range(10)] for k in range(10)]

def bfs(qs,zd):
    qs.append(0)
    q.put(qs)
    vis[qs[0]][qs[1]][qs[2]][qs[3]]=1
    while(q.empty()==False):
        now=q.get()
        if now[0]==zd[0] and now[1]==zd[1] and now[2]==zd[2] and now[3]==zd[3]:
            print(now[4])
            return  #出口

        for i in range(4): #-1
            next=now.copy()
            next[i]-=1
            if next[i]==0:
                next[i]=9
            if vis[next[0]][next[1]][next[2]][next[3]] != 1:
                vis[next[0]][next[1]][next[2]][next[3]] = 1
                next[4]+=1
                q.put(next)
                #print(next)


        for i in range(4): #+1
            next=now.copy()
            next[i]+=1
            if next[i]==10:
                next[i]=1
            if vis[next[0]][next[1]][next[2]][next[3]]!=1:
                vis[next[0]][next[1]][next[2]][next[3]] = 1
                next[4]+=1
                q.put(next)
                #print(next)


        for i in range(3): #交换
            next = now.copy()
            a=next[i]
            next[i]=next[i+1]
            next[i+1] = a
            if vis[next[0]][next[1]][next[2]][next[3]] != 1:
                vis[next[0]][next[1]][next[2]][next[3]] = 1
                next[4]+=1
                q.put(next)
                #print(next)
    return -1

bfs(qs,zd)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个基于C++的BFS维迷宫中最短路径的示例代码: ```cpp #include <iostream> #include <queue> #include <cstring> using namespace std; const int MAXN = 1005; // 最大节点数 const int INF = 0x3f3f3f3f; // 无穷大 int n, m; // n表示迷宫的行数,m表示迷宫的列数 int sx, sy, ex, ey; // 起点和终点的坐标 int maze[MAXN][MAXN]; // 存储迷宫的地图 int dis[MAXN][MAXN]; // 存储起点到每个节点的距离 bool vis[MAXN][MAXN]; // 记录每个节点是否被访问过 struct node { int x, y; // 节点坐标 }; void bfs() { memset(dis, INF, sizeof(dis)); // 初始化距离为无穷大 memset(vis, false, sizeof(vis)); // 初始化所有节点都未被访问过 dis[sx][sy] = 0; // 起点到自己的距离为0 vis[sx][sy] = true; // 起点已经访问过了 queue<node> q; // 定义一个队列,用于广度优先搜索 q.push({sx, sy}); // 将起点加入队列 while (!q.empty()) { node u = q.front(); q.pop(); // 取出队首节点 int dx[4] = {0, 0, 1, -1}; // 四个方向 int dy[4] = {1, -1, 0, 0}; for (int i = 0; i < 4; ++i) { int x = u.x + dx[i]; int y = u.y + dy[i]; if (x >= 1 && x <= n && y >= 1 && y <= m && maze[x][y] != 1 && !vis[x][y]) { // 如果这个点可行且未被访问过 dis[x][y] = dis[u.x][u.y] + 1; // 更新距离 vis[x][y] = true; // 标记为已访问 q.push({x, y}); // 将其加入队列 } } } } int main() { cin >> n >> m; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { cin >> maze[i][j]; } } cin >> sx >> sy >> ex >> ey; bfs(); cout << "起点到终点的最短距离为:" << dis[ex][ey] << endl; return 0; } ``` 这段代码使用维数组存储迷宫地图和节点距离,时间复杂度为O(nm),其中n表示迷宫的行数,m表示迷宫的列数。需要注意的是,在实际使用中,可能需要根据具体情况调整代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值