天天看点

python迷宫寻路_迷宫寻路

57

//AC代码:

#include

#include

#include

#include

using namespace std;

char G[105][105];

int book[105][105][1200],N,M;

int Next[4][2]={0,1,0,-1,1,0,-1,0};

int bfs(int,int);

struct node{

int x,y,k,step;

node(int x,int y,int k,int step):x(x),y(y),k(k),step(step){}

};

int main(){

int i,j;

//freopen("input.txt","r",stdin);

while(scanf("%d%d",&N,&M)!=EOF){

for(i=0;i

memset(book,0,sizeof(book));

int flag=0;

for(i=0;i

if(flag==1) break;

for(j=0;j

if(G[i][j]=='2'){

flag=1;

book[i][j][0]=1;

printf("%d\n",bfs(i,j));

break;

}

}

}

}

int bfs(int startX,int startY){

queue Q;

Q.push(node(startX,startY,0,0));

while(!Q.empty()){

node head=Q.front();Q.pop();

if(G[head.x][head.y]=='3') return head.step;

for(int i=0;i<4;i++){

int nx=head.x+Next[i][0],ny=head.y+Next[i][1];

if(nx>=N||nx<0||ny>=M||ny<0||G[nx][ny]=='0') continue;

int key=head.k;

if('a'<=G[nx][ny]&&G[nx][ny]<='z') key=key|(1<

if('A'<=G[nx][ny]&&G[nx][ny]<='Z'&&(key&(1<

if(!book[nx][ny][key]){

book[nx][ny][key]=1;

Q.push(node(nx,ny,key,head.step+1));

}

}

}

return 0;

}//这题就是普通的bfs多了‘钥匙’这个状态

//所以book[x][y][key]的意义就是 横坐标为x,纵坐标为y,钥匙状态为key的点是否访问过

//钥匙的状态 就用二进制数表示 最多10 把钥匙 那就是1024

//比如我现在有第二把钥匙和第四把钥匙 那么我的钥匙状态就是 0101000000 也就是 320

编辑于 2017-08-06 11:23:31

回复(36)

13

import java.util.*;

public class Main {

static class Node{

int x;

int y;

int key;

int step;

public Node(int x,int y,int key,int step){

this.x=x;

this.y=y;

this.key=key;

this.step=step;

}

}

public static void main(String[] args){

Scanner in=new Scanner(System.in);

int N=in.nextInt();

int M=in.nextInt();

in.nextLine();

char[][] G=new char[N][M];

for(int i=0;i

G[i]=in.nextLine().toCharArray();

}

for(int i=0;i

for(int j=0;j

if(G[i][j]=='2'){

System.out.println(bfs(i,j,N,M,G));

return;

}

}

}

}

private static int bfs(int si, int sj,int N,int M,char[][] G) {

Queue queue=new LinkedList<>();

int[][][] mp=new int[101][101][1025];

int[][] next={{-1,0},{0,-1},{1,0},{0,1}};

queue.offer(new Node(si,sj,0,0));

while(!queue.isEmpty()){

Node node=queue.poll();

for(int i=0;i<4;i++){

int x=node.x+next[i][0];

int y=node.y+next[i][1];

int key=node.key;

if(x<0||x>=N||y<0||y>=M||G[x][y]=='0') continue;

else if(G[x][y]=='3') return node.step+1;

else if(G[x][y]<='z'&&G[x][y]>='a') key=key|(1<

else if(G[x][y]<='Z'&&G[x][y]>='A'&&(key&(1<

if(mp[x][y][key]==0){

mp[x][y][key]=1;

queue.offer(new Node(x,y,key,node.step+1));

}

}

}

return -1;

}

}

编辑于 2017-08-07 01:17:32

回复(8)

8

import java.util.*;

// 使用带有计数的层序遍历,求得最短根叶长度

// 带有附加钥匙限制的情况下,用更高维的数组记录是否访问过

// 该题实际字母字符不会超过j

public class Main{

public static void main(String[] args){

Scanner sc = new Scanner(System.in);

int m = sc.nextInt(), n = sc.nextInt();

char[][] maze = new char[m][n];

sc.nextLine();

for(int i = 0; i < m; i++) maze[i] = sc.nextLine().toCharArray();

sc.close();

for(int i = 0; i < m; i++)

for(int j = 0; j < n; j++)

if(maze[i][j] == '2') {System.out.println(solution(maze,i,j)); return;}

}

private static int solution(char[][] maze, int startX, int startY){

int res = 0;

int m = maze.length, n = maze[0].length;

boolean[][][] isVisted = new boolean[m][n][1024];

isVisted[startX][startY][0] = true;

int[][] dir = {{-1,0},{1,0},{0,-1},{0,1}};

Queue queue = new LinkedList<>();

queue.offer(startX); queue.offer(startY); queue.offer(0);

while(!queue.isEmpty()){

int num = queue.size()/3; // 带有计数的层序遍历

res++; // 层数

while(num > 0){

startX = queue.poll(); startY = queue.poll(); int k = queue.poll();

num--;

for(int i = 0; i < 4; i++){

int x = startX + dir[i][0]; int y = startY + dir[i][1]; int key = k;

if(x<0 || x>=m || y<0 || y>=n || maze[x][y] == '0') continue;

else if(maze[x][y] == '3') return res;

else if(maze[x][y] <= 'j' && maze[x][y] >= 'a') key = key | 1 << maze[x][y]-'a';

else if(maze[x][y] <= 'J' && maze[x][y] >= 'A' && (key & 1 << maze[x][y]-'A') == 0) continue;

if(isVisted[x][y][key] == false){ // 注意不能加else 也不能加 == '1',否则缺少小写字符的情况

isVisted[x][y][key] = true;

queue.offer(x); queue.offer(y); queue.offer(key);

}

}

}

}

return -1;

}

}

发表于 2019-02-13 16:53:07

回复(3)

3

层次遍历。有几点需要注意:

1、需要标记已访问节点,注意不是在原图中标记,访问的节点不仅包含坐标,还包含钥匙状态

2、使用int的位来存储钥匙状态,用位运算来判断钥匙,钥匙获得后可重复使用

#include

#include

#include

using namespace std;

struct Node {

int x, y, k;

Node(int x, int y, int k) : x(x), y(y), k(k) {}

};

char G[110][110];   // graph

int V[110][110][1100];  // visited

int main() {

int M, N;

cin >> M >> N;

for (int i = 0; i < M; i++) {

for (int j = 0; j < N; j++) {

cin >> G[i][j];

}

}

queue Q;

int res = 0;

for (int i = 0; i < M; i++) {

for (int j = 0; j < N; j++) {

if (G[i][j] == '2') {

Q.push(Node(i, j, 0));

while (!Q.empty()) {

int n = Q.size();

res++;

while (n--) {

auto node = Q.front();

Q.pop();

int dx[] = {-1, 0, 1, 0};

int dy[] = {0, 1, 0, -1};

for (int d = 0; d < 4; d++) {

int x = node.x + dx[d];

int y = node.y + dy[d];

if (x >= 0 && x < M && y >= 0 && y < N && G[x][y] != '0' && V[x][y][node.k] == 0) {

V[x][y][node.k] = 1;

if (G[x][y] >= 'a' && G[x][y] <= 'z') {

Q.push(Node(x, y, node.k | (1 << (G[x][y] - 'a'))));

} else if (G[x][y] >= 'A' && G[x][y] <= 'Z') {

if (((1 << (G[x][y] - 'A')) & node.k) > 0) {

Q.push(Node(x, y, node.k));

}

} else if (G[x][y] == '3') {

cout << res << endl;

return 0;

} else {

Q.push(Node(x, y, node.k));

}

}

}

}

}

break;

}

}

}

return 0;

}

运行时间:172ms

占用内存:43512k

发表于 2019-03-16 21:13:52

回复(4)

2

//学习的大家的代码(加注释),没想到用bit位来表示每个门的钥匙状态,规定时间未完成,后附自己的方法,超时了

import java.util.LinkedList;

import java.util.Queue;

import java.util.Scanner;

class Node {

int x;

int y;

int keys;

int deep;

public Node(int x, int y, int keys, int deep) {

super();

this.x = x;

this.y = y;

this.keys = keys;

this.deep = deep;

}

}

public class Main1 {

// maze迷宫,isVisited表示状态是否有过,有过就是true start开始结点

public static int BFS(char[][] maze, boolean[][][] isVisited, Node start) {

Queue queue = new LinkedList<>(); // bfs队列

queue.add(start);

isVisited[start.x][start.y][0] = true; // 用比特位来表示对应为门是否有要是

// 'A'表示标号为0位的门是否有钥匙

int[][] dirs = new int[][] { { 0, -1 }, { 0, 1 }, { 1, 0 }, { -1, 0 } };

Node now, next; // now 表示当前结点,next表示要进入队列的结点

int M = maze.length;

int N = maze[0].length;

while (!queue.isEmpty()) {

now = queue.poll();

if (maze[now.x][now.y] == '3') { // 如果该点是终点 结束

return now.deep;

}

for (int i = 0; i < 4; i++) {

//当前如果是钥匙,next.keys在下面的步骤会改变

next = new Node(now.x + dirs[i][0], now.y + dirs[i][1], now.keys, now.deep+1);

if (next.x < 0 || next.x >= M || next.y < 0 || next.y >= N

|| maze[next.x][next.y] == '0') { //不能走就不进入队列

continue;

}

if (maze[next.x][next.y] <= 'Z' && maze[next.x][next.y] >= 'A'

&&(now.keys&(1<

continue; //next结点为门,now没有对应钥匙就不走(next 不进队列)

}

if (maze[next.x][next.y] <= 'z' && maze[next.x][next.y] >= 'a') {

//是钥匙 就将next.keys重新赋值

next.keys=next.keys|1<

}

if (!isVisited[next.x][next.y][now.keys]) {

//next的状态没来过就标记

isVisited[next.x][next.y][now.keys]=true;

//next 进入队列

queue.add(next);

}

}

}

return -1;

}

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

while (sc.hasNext()) {

String[] strings = sc.nextLine().split(" ");

int M = Integer.valueOf(strings[0]);

int N = Integer.valueOf(strings[1]);

char[][] maze = new char[M][N];

Node start = new Node(0, 0, 0, 0);

int gate=0;

for (int i = 0; i < M; i++) {

maze[i] = sc.nextLine().toCharArray();

for (int j = 0; j < N; j++) {

//找起点

if (maze[i][j] == '2') {

start.x = i;

start.y = j;

}

//统计一共多少门

if (maze[i][j] <= 'Z'&&maze[i][j] >= 'A') {

gate++;

}

}

}

//所有状态的 访问情况

boolean[][][]isVisited=new boolean[M][N][2<

//只输出路径的步数(不包括起点)

System.out.println(BFS(maze, isVisited, start));

}

sc.close();

}

}

/

public static int maze(char A[][]) {

int i = 0, j = 0;

for (i = 0; i < A.length; ++i)

for (j = 0; j < A[0].length; ++j)

if (A[i][j] == '2')

return bfs(A, i, j);

return -1;

}

public static int bfs(char A[][], int i, int j) {

int m = A.length, n = A[0].length;

boolean visit[][][] = new boolean[m][n][1200];

Queue queue = new LinkedList<>();

int direction[][] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};//左右上下

node p = new node(i, j, 0, 0);

visit[i][j][0] = true;

queue.add(p);

while (!queue.isEmpty()) {

node q = queue.poll();

if (A[q.x][q.y] == '3')

return q.level;

for (i = 0; i < 4; ++i) {

p = new node(q.x + direction[i][0], q.y + direction[i][1], q.keys, q.level + 1);

if (p.x < 0 || p.x >= m || p.y < 0 || p.y >= n || A[p.x][p.y] == '0') {

continue;

}

//遇见门且没钥匙

if (A[p.x][p.y] >= 'A' && A[p.x][p.y] <= 'Z' && ((1 << (A[p.x][p.y] - 'A')) & q.keys) == 0) {

continue;

}

if (A[p.x][p.y] >= 'a' && A[p.x][p.y] <= 'z') {

p.keys = q.keys | (1 << (A[p.x][p.y] - 'a'));

}

if (!visit[p.x][p.y][p.keys]) {

visit[p.x][p.y][p.keys] = true;

queue.add(p);

}

}

}

return -1;

}

}

class node {

int x;

int y;

int keys;

int level;

public node(int i, int j, int k, int l) {

x = i;

y = j;

keys = k;

level = l;

}

}

发表于 2019-01-15 22:23:46

回复(1)

1

#include

#include

#include

#include

#include

#include

using namespace std;

int offset[4][2] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}};

int book[100][100][1024] = {0};

struct node{ int x, y, key, step; node(int x, int y, int key, int step):x(x), y(y), key(key), step(step){}

};

int bfs(vector maze, int x, int y)

{ queue Q; Q.push(node(x, y, 0, 0)); while (!Q.empty()) { node h = Q.front(); Q.pop(); if(maze[h.y][h.x] == '3') return h.step; for (int i = 0; i < 4; i++) { int nx = h.x + offset[i][0], ny = h.y + offset[i][1]; if(nx < 0 || nx >= maze[0].size() || ny < 0 || ny >= maze.size() || maze[ny][nx] == '0') continue; int keyState = h.key; if(maze[ny][nx] >= 'a' && maze[ny][nx] <= 'z') keyState |= (1 << (maze[ny][nx] - 'a'));//捡钥匙 if(maze[ny][nx] >= 'A' && maze[ny][nx] <= 'Z' && (keyState & (1 << (maze[ny][nx] - 'A'))) == 0)  continue; //没有打开门的钥匙 if(!book[ny][nx][keyState]) { book[ny][nx][keyState] = 1; Q.push(node(nx, ny, keyState, h.step + 1)); } } } return 0;

}

int main()

{

int m, n;

vector mp;//存储迷宫

cin >> m >> n;

while(m--)

{

string s;

cin >> s;

mp.push_back(s);

} int flag = 0;

for(int j = 0; j < mp.size(); j++)

{

for(int i = 0; i < n; i++)

{

if(mp[j][i] == '2') { flag = 1; book[j][i][0] = 1; cout << bfs(mp, i, j) << endl; break; }

} if(1 == flag) break;

}

return 0;

}

发表于 2019-03-08 22:03:58

回复(0)

像求助一下,用的A*写的,可是居然会超时。我怎么觉得比bfs算法复杂度低呢?

# 读取输入数据

[M,N]= list(map(int,input().split()))

maxz = []

for x in range(M):

maxz.append(list(input()))

# -------------------------------------------------

# M=5

# N=5

# maxz=[['0','2','1','1','1'],

#       ['0','1','a','0','A'],

#       ['0','1','0','0','3'],

#       ['0','1','0','0','1'],

#       ['0','1','1','1','1']]

# -------------------------------------------------

# 数据初始化

start0 = []

end0 = []

# 提取所有带字母的钥匙和门

dicta = []

dictb = []

for x in range(M):

for y in range(N):

if maxz[x][y] == '2':

start0 = [x, y]

elif maxz[x][y] == '3':

end0 = [x, y]

elif 96 

dicta.append([maxz[x][y], x, y])

# 按钥匙字母排序

dicta.sort(key=lambda x: x[0])

lena = len(dicta)

# 转换成钥匙和门的组合

for x in range(lena // 2):

dictb.append(dicta[(lena // 2) + x][1:3])

dictb.append(dicta[x][1:3])

# ---------------------------------------------------------

# 计算 G,H,F,P值   G为当前点到起点的距离,H为当前点到终点的距离,F为G+H,P为来源点

def distance(Node_current7, yuandian, start8, end8):

P = yuandian

G = abs(Node_current7[0] - start8[0]) + abs(Node_current7[1] - start8[1])

H = abs(Node_current7[0] - end8[0]) + abs(Node_current7[1] - end8[1])

F = G + H

return [F, P]

# 查找周围的临接点

def findNeighbors(nc, maxz9, Node_start7, Node_end7):

open_list9 = []

if nc[0] > 0:  # 取上面的点

if maxz9[nc[0] - 1][nc[1]] != '0':

open_list9.append([nc[0] - 1, nc[1], distance([nc[0] - 1, nc[1]], nc[0:2], Node_start7, Node_end7)])

if nc[0] 

if maxz9[nc[0] + 1][nc[1]] != '0':

open_list9.append([nc[0] + 1, nc[1], distance([nc[0] + 1, nc[1]], nc[0:2], Node_start7, Node_end7)])

if nc[1] > 0:  # 取左面的点

if maxz9[nc[0]][nc[1] - 1] != '0':

open_list9.append([nc[0], nc[1] - 1, distance([nc[0], nc[1] - 1], nc[0:2], Node_start7, Node_end7)])

if nc[1] 

if maxz9[nc[0]][nc[1] + 1] != '0':

open_list9.append([nc[0], nc[1] + 1, distance([nc[0], nc[1] + 1], nc[0:2], Node_start7, Node_end7)])

return open_list9

# 从openlist找到F值最小

def findMinNode(openlist_temp):

y1 = openlist_temp[0]

for x1 in openlist_temp:

if y1[2][0] > x1[2][0]:

y1 = x1

return y1

# A*搜索

def aStarSearch(Node_start, Node_end, maxz0):

OpenList = []

CloseList = []

Node_current = []

List_neighbors = []

term_result = []

#     把起点加入 open list

OpenList.append([Node_start[0], Node_start[1], [0, [-1, -1]]])

#     主循环,每一轮检查一个当前方格节点

while len(OpenList) > 0:

# 在OpenList中查找 F值最小的节点作为当前方格节点

Node_current = findMinNode(OpenList)

# 当前方格节点从open list中移除

OpenList.remove(Node_current)

# 当前方格节点进入 close list

CloseList.append(Node_current)

# 找到所有邻近节点

List_neighbors = findNeighbors(Node_current, maxz0, Node_start, Node_end)

for x in List_neighbors:

if (x not in OpenList) & (x not in CloseList):

# 邻近节点不在OpenList,CloseList中,标记父亲、G、H、F,并放入OpenList

OpenList.append(x)

# 如果终点在OpenList中,直接返回路径

for x in OpenList:

if Node_end == x[0:2]:  # 如果找到

term_result.append(x[0:2])

temp0 = x

while Node_start != temp0[0:2]:

for z in CloseList:

if temp0[2][1] == z[0:2]:

temp0 = z

term_result.append(temp0[0:2])

break

term_result.pop()

# print(term_result[::-1])

return len(term_result)

# OpenList用尽,仍然找不到终点,说明终点不可到达,返回空

return None

#逐个遍历各个位置,从起点 到第一个钥匙,然后再到第一个门,如果有其他钥匙,再循环,最后去出口。循环计算两点间的距离。

dictb.insert(0, start0)

dictb.append(end0)

sum0 = 0

for y in range(len(dictb) - 1):

sum0 += aStarSearch(dictb[y], dictb[y + 1], maxz)

print(sum0)

发表于 2020-02-09 15:57:26

回复(0)

#include

using namespace std;

int x[4] = {0,0,1,-1};

int y[4] = {1,-1,0,0};

int min_path = INT_MAX;

int m,n;

void dfs(char** maze, int path, int i, int j, int key, bool*** visit)

{

if(path>=min_path) return;//剪枝

if(i<0||i>=m||j<0||j>=n||maze[i][j]=='0'||visit[i][j][key]) return;//无效

if(maze[i][j]>='a'&&maze[i][j]<='z')

{

key = key | (1<

}

else if(maze[i][j]>='A'&&maze[i][j]<='Z'&&((key&(1<

{

return;

}//无钥匙过不了门

else if(maze[i][j]=='3')

{

min_path = min(min_path, path);

return;

}//到终点

visit[i][j][key] = true;

for(int k=0;k<4;k++)

{

int nexti = i + x[k];

int nextj = j + y[k];

dfs(maze, path+1, nexti, nextj, key, visit);

}

visit[i][j][key] = false;

}

int main()

{

cin>>m>>n;

//    vector> maze(m, vector(n));

char** maze = new char*[m];

bool*** visit = new bool**[m];

//    visit.assign(m, vector>(n,vector(1024,false)));

int sx,sy;

for(int i=0;i

{

visit[i] = new bool*[n];

maze[i] = new char[n];

for(int j=0;j

{

visit[i][j] = new bool[1024];

cin>>maze[i][j];

if(maze[i][j]=='2')

{

sx = i;

sy = j;

}

}

}

dfs(maze, 0, sx, sy,0,visit);

cout<

} 只过了30%,然后超时,求大神解答。。。

发表于 2019-07-29 01:25:58

回复(0)

为什么这么多不剪枝的BFS能通过?

难道不会反复横跳吗

发表于 2019-07-27 18:18:28

回复(1)

#include

using namespace std;

bool vis[1024][101][101];

int n,m;

char mp[102][102];

int sx,sy;

struct node

{

int x,y;

int status;

int dis;

node(){}

node(int xx,int yy,int status,int dis):x(xx),y(yy),status(status),dis(dis) {}

};

int dx[]={-1,1,0,0};

int dy[]={0,0,-1,1};

queue q;

int main(int argc, char const *argv[]){

cin>>n>>m;

for(int i=1;i<=n;++i)

cin>>mp[i]+1;

for(int i=1;i<=n;++i)

for(int j=1;j<=m;++j)

if(mp[i][j]=='2'){

sx=i,sy=j;

goto loop;

}

loop:;

node p;

vis[0][sx][sy]=1;

q.push(node(sx,sy,0,0));

while(!q.empty()) {

p=q.front();

q.pop();

// printf("%d %d %d %d\n\n",p.status,p.x,p.y,p.dis );

// vis[p.status][p.x][p.y]=1;

if(mp[p.x][p.y]=='3'){

cout<

break;

}

for(int i=0;i<4;++i) {

int xx=p.x+dx[i],yy=p.y+dy[i];

if(xx<=0||xx>n||yy<=0||yy>m||mp[xx][yy]=='0'||vis[p.status][xx][yy]) continue;

if(mp[xx][yy]>='A'&&mp[xx][yy]<='Z') {

if(p.status&(1<

vis[p.status][xx][yy]=1;

q.push(node(xx,yy,p.status,p.dis+1));

}

}

else if(mp[xx][yy]>='a'&&mp[xx][yy]<='z') {

vis[p.status|(1<

q.push(node(xx,yy,p.status|(1<

}

else{

vis[p.status][xx][yy]=1;

q.push(node(xx,yy,p.status,p.dis+1));

}

}

}

return 0;

}

发表于 2019-06-23 16:18:28

回复(0)

m,n = list(map(int, input().split()))

roads = []  #存储地图

route_stack = []

book = [[[0 for z in range(1024)] for x in range(52)] for y in range(52)]

# 读入数据,找到起始位置

for i in range(m):

tmp = list(input())

roads.append(tmp)

if "2" in tmp:

sx, sy = i, tmp.index("2")

route_stack.append([sx,sy,0,0]) # 坐标x,y,存储钥匙,步数step,

step = 0

# 可以移动的位子,分别对应右左上下

dxs = [1, -1, 0, 0]

dys = [0, 0, 1, -1]

i = 0  # 标记点位置

# bfs广度搜索

# bfs广度搜索

while route_stack: # 不为空则可以继续

head = route_stack.pop(0)

if roads[head[0]][head[1]] == '3':

print(head[3])

break

#开始走路

for dx,dy in zip(dxs,dys):

key = head[2]

nx = head[0] + dx

ny = head[1] + dy

if nx < 0 or nx >= m or ny < 0 or ny >= n or roads[nx][ny] == '0':

continue

if "a" <= roads[nx][ny] <= "z":

key = head[2]|(1<

if ('A'<=roads[nx][ny] and roads[nx][ny]<='Z') and (key&(1<

continue

if not book[nx][ny][key] :

book[nx][ny][key]=1

route_stack.append([nx,ny,key,head[3]+1])

求助,按着@元气の悟空的思路用python写的,30%通过,提示数组越界。

发表于 2019-06-12 11:12:59

回复(0)

import java.util.*;

public class Main{

public static void main(String[] arg){

Scanner sc=new Scanner(System.in);

while(sc.hasNext()){

int n=sc.nextInt();

int m=sc.nextInt();

char[][] A=new char[n][m];

int[] start=new int[2];

int[] end=new int[2];

int[][] dir=new int[][]{{0,-1},{-1,0},{1,0},{0,1}};

for(int i=0;i

String row=sc.next();

for(int j=0;j

A[i][j]=row.charAt(j);

if(A[i][j]=='2'){

start[0]=i;

start[1]=j;

}else if(A[i][j]=='3'){

end[0]=i;

end[1]=j;

}

}

}

boolean[][][] visited=new boolean[n][m][1<<10];

LinkedList queue=new LinkedList<>();

queue.add(new int[]{start[0],start[1],0});

visited[start[0]][start[1]][0]=true;

int cnt=0;

out:

while(queue.size()>0){

cnt++;

int len=queue.size();

while(len-->0){

int[] q=queue.poll();

int x=q[0],y=q[1],keys=q[2];

for(int i=0;i<4;i++){

int nx=x+dir[i][0];

int ny=y+dir[i][1];

if(nx==end[0]&&ny==end[1]) break out;

int nkeys=keys;

if(nx<0||nx>=n||ny<0||ny>=m||A[nx][ny]=='0') continue;

//int r=0;

if('a'<=A[nx][ny]&&A[nx][ny]<='z'){

int key=A[nx][ny]-'a';

nkeys=(1<

}else if('A'<=A[nx][ny]&&A[nx][ny]<='Z'){

int key=A[nx][ny]-'A';

if(((nkeys>>key)&1)==0) continue;

}

if(visited[nx][ny][nkeys]) continue;

visited[nx][ny][nkeys]=true;

queue.add(new int[]{nx,ny,nkeys});

}

}

}

System.out.println(cnt);

}

}

}

编辑于 2019-06-06 03:07:17

回复(0)

#include

#include

#include

using namespace std;

struct Point

{

int x;

int y;

int key = 0;//钥匙

};

int X[] = {0,1,0,-1};

int Y[] = {1,0,-1,0};

int main()

{

int m=0, n=0;

char input;

vector row;

vector> map;

cin>>m>>n;

//构建地图

for(int i=0; i

{

row.clear();

for(int j=0; j

{

cin>>input;

row.push_back(input);

}

map.push_back(row);

}

//定位出发点与终点

Point start, end;

for(int i=0; i

for(int j=0; j

{

if(map[i][j] == '2')

{

start.x = i;

start.y = j;

}

else if(map[i][j] == '3')

{

end.x = i;

end.y = j;

}

}

//开始寻路

int step = 10000000, key = 0;

bool ifFind = false;

char ch;

Point temp;

Point add;

queue q;

short value[100][100] = {0};

q.push(start);

while(!q.empty())

{

temp = q.front();

q.pop();

for(int i=0; i<4; i++)

{

if(temp.x+X[i]>=0 && temp.y+Y[i]>=0 && temp.x+X[i]

{

ch = map[temp.x+X[i]][temp.y+Y[i]];

switch(ch)

{

case '0':break;

case '1'://不是钥匙或者门周围,走过的路就不再走了

//  if(value[temp.x+X[i]][temp.y+Y[i]] == 0)

// {

value[temp.x+X[i]][temp.y+Y[i]] = value[temp.x][temp.y]+1;

add.x = temp.x+X[i];

add.y = temp.y+Y[i];

add.key = temp.key;

q.push(add);

//  }

break;

case '2':break;

case '3':

ifFind = true;

value[temp.x+X[i]][temp.y+Y[i]] = value[temp.x][temp.y]+1;

if(value[temp.x+X[i]][temp.y+Y[i]]

step = value[temp.x+X[i]][temp.y+Y[i]];

break;

default:

if(ch>='a' && ch<='j')//钥匙

{

key |= 1<

value[temp.x+X[i]][temp.y+Y[i]] = value[temp.x][temp.y]+1;

add.x = temp.x+X[i];

add.y = temp.y+Y[i];

add.key = key;

q.push(add);

}

if(ch>='A' && ch<='J')//门

if(temp.key & (1<

{

value[temp.x+X[i]][temp.y+Y[i]] = value[temp.x][temp.y]+1;

add.x = temp.x+X[i];

add.y = temp.y+Y[i];

add.key ^= 1<

q.push(add);

}

break;

}

}

if(ifFind)

break;

}

if(ifFind)

break;

}

cout<

return 0;

} 求大佬帮忙看看,报段错误,但是都有检查,有防止越界的,实在是找不到问题在哪

编辑于 2019-05-09 20:03:10

回复(0)