java迷宫寻宝_迷宫寻宝(一) BFS

#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include

using namespacestd;

typedeflong longLL;

typedef unsignedlong longULL;#define MAXN 22

#define LLL 1000000000

#define INF 1000000009

#define eps 0.00000001

/*BFS 搜索,在读入图的时候记录abcde所需要的钥匙个数

先BFS一遍,找到所有能找到的钥匙。

然后对于所有的门,如果第一次搜索能到达而且钥匙足够。

把这个门加入队列再搜*/

structnode

{intx, y;

node()= default;

node(int _x,int_y):x(_x),y(_y){}

};

node start,aim;

vector door[5];int key[5], num[5], n, m;//需要的钥匙个数,n行m列

int x[4] = { 0,0,1,-1 }, y[4] = { 1,-1,0,0};boolbeen[MAXN][MAXN];charg[MAXN][MAXN];intcheck()

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

{if (key[i]>0&&num[i] ==key[i])

{for (int j = 0; j < door[i].size(); j++)

{if(been[door[i][j].x][door[i][j].y])returni;

}

}

}return -1;

}boolBFS(node s)

{

queueq;

been[s.x][s.y]= true;

q.push(s);while (!q.empty())

{

node tmp=q.front();

q.pop();//cout << tmp.x << ' ' << tmp.y << ' '<

if (tmp.x == aim.x&&tmp.y ==aim.y)return true;if ((g[tmp.x][tmp.y] - 'A' >= 0 && g[tmp.x][tmp.y] - 'A'<5)&&(key[g[tmp.x][tmp.y] - 'A']==0||num[g[tmp.x][tmp.y] - 'A'] != key[g[tmp.x][tmp.y] - 'A']))continue;for (int i = 0; i < 4; i++)

{int tx = tmp.x + x[i], ty = tmp.y +y[i];if (tx >= 0 && tx < n& ty >= 0 && ty <= m&&!been[tx][ty]&&((g[tx][ty]=='.'||g[tx][ty]=='G'||g[tx][ty]-'A'>=0&&g[tx][ty]-'A'<5)||(g[tx][ty]-'a'>=0&&g[tx][ty]-'a'<5)))

{if(g[tx][ty] - 'a' >= 0 && g[tx][ty] - 'a'<5)

num[g[tx][ty]- 'a']++;

been[tx][ty]= true;

q.push(node(tx, ty));

}

}

}return false;

}intmain()

{while (scanf("%d%d", &n, &m), n+m)

{bool f = false;

memset(been,false, sizeof(been));

memset(num,0, sizeof(num));

memset(key,0, sizeof(key));for (int i = 0; i < 5; i++)

{

door[i].clear();

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

{

scanf("%s", g[i]);for (int j = 0; j < m; j++)

{if (g[i][j] - 'A' >= 0 && g[i][j] - 'A' < 5)

{

door[g[i][j]- 'A'].push_back(node(i, j));

}else if (g[i][j] - 'a' >= 0 && g[i][j] - 'a' < 5)

{

key[g[i][j]- 'a']++;

}else if (g[i][j] == 'S')

{

start.x= i, start.y =j;

}else if (g[i][j] == 'G')

{

aim.x= i, aim.y =j;

}

}

}if(BFS(start))

{

f= true;

printf("YES\n");continue;

}while (1)

{int k =check();if (k == -1) break;for (int j = 0; j < door[k].size(); j++)

{if(been[door[k][j].x][door[k][j].y])

{if(BFS(door[k][j]))

{

f= true;break;

}

door[k].erase(door[k].begin()+j);

}

}if(f)break;

}if (!f)

printf("NO\n");elseprintf("YES\n");

}return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的迷宫寻宝最短路径代码示例,使用广度优先搜索算法和队列: ```java import java.util.LinkedList; import java.util.Queue; public class Maze { // 定义迷宫,0 表示通路,1 表示障碍物 private int[][] maze = { {0, 1, 0, 0, 0}, {0, 1, 0, 1, 0}, {0, 0, 0, 0, 0}, {0, 1, 1, 1, 0}, {0, 0, 0, 1, 0} }; // 定义开始和结束坐标 private int[] start = {0, 0}; private int[] end = {4, 4}; // 定义搜索函数 public int bfs() { Queue<int[]> queue = new LinkedList<>(); // 用队列来实现广度优先搜索 queue.offer(start); int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; // 定义四个方向 int steps = 0; while (!queue.isEmpty()) { int size = queue.size(); for (int i = 0; i < size; i++) { int[] curr = queue.poll(); if (curr[0] == end[0] && curr[1] == end[1]) { return steps; } for (int[] dir : dirs) { int x = curr[0] + dir[0]; int y = curr[1] + dir[1]; if (x >= 0 && x < maze.length && y >= 0 && y < maze[0].length && maze[x][y] == 0) { maze[x][y] = 1; // 标记为已经访问过 queue.offer(new int[]{x, y}); } } } steps++; // 记录步数 } return -1; // 没有找到终点 } // 测试函数 public static void main(String[] args) { Maze maze = new Maze(); int steps = maze.bfs(); if (steps != -1) { System.out.println("找到宝藏,最短路径为 " + steps + " 步!"); } else { System.out.println("没有找到宝藏..."); } } } ``` 运行结果: ``` 找到宝藏,最短路径为 8 步! ``` 这个示例代码使用了广度优先搜索算法,在搜索过程中使用一个队列来实现。首先将起点加入队列中,然后每次从队列中取出一个节点,判断是否是终点,如果是,则搜索结束,返回步数;否则,将该节点的邻居节点加入队列中继续搜索,同时将该节点标记为已经访问过。搜索结束后,如果能够找到终点,则返回最短路径的步数,否则返回 -1。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值