获取钥匙

这题目标是通过移动拿到所有钥匙,上锁的房间需要对应的钥匙,思路是通过|和&二进制判断是否有对应钥匙,与普通不同的是,不同点是当我重复进入一个房间时,不能单纯通过有无来过来判断是否continue,而是要通过进入这个房间时钥匙的状况来判断

点击查看代码
			struct node {
				int x, y, w;// 代表在x,y位置时有w个钥匙 
			};
			queue<node> q;
			int d[6] = {-1, 0, 1, 0};
			int d1[6]={0,1,0,-1}// fangxiang
			int vis[200][200][13];
			memset(vis,0,sizeof(0));
			int key = 0;
			int n = a.size(), m = a[0].size();
			for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
					if (a[i][j] == '@') {//代表起点,入队 
						q.push({i, j, 0});
					}
					if (a[i][j] >= 'a' && a[i][j] <= 'f') {
						key |= 1 << (a[i][j] - 'a');//,小写是钥匙更新钥匙的状态,说明最终要获得多少个钥匙; 
					}
				}
			}
			int s = 0;
			while (q.size()) {
				for (int i = 0; i < q.size(); i++) {
					node from= q.front();
					q.pop();
					for (int i = 0; i < 4; i++) {
						int x1 = from.x + d[i];
						int y1 = from.y + d1[i];
						if (x1>=0 && x1 < n &&y1 >= 0 &&y1 < m) {
							char c = a[x1][y1];
							int w1 = from.w;
							if (c == '#') {//撞墙跳过 
								continue;
							}
							if (c >= 'a' && c <= 'f') {//小写是钥匙 ,w1是当前钥匙总数 
								w1 |= (1 << (c - 'a'));
							}
							if (c >= 'A' && c <= 'F') {
								if ((w1 & (1 << (c - 'A'))) == 0) {//大写是锁,&有一出一,1和1碰到就代表当前有需要能开锁的钥匙 
									continue;
								}
							}
							if (w1 == key) {//如果所有的钥匙都有,直接返回当钱层数 
								return s + 1;
							}
							if (!vis[x1][y1][w1]) {//如果没在当前钥匙状态下访问过当前节点,入队 
								vis[x1][y1][w1] = 1;
								q.push({x1, y1, w1});
							}
						}
					}
				}
				s++;//增加层数,如果放for会不知道是哪一层,层数会多; 
			}
			return -1;//无法获得所有钥匙就返回 
posted @ 2024-07-22 20:27  台州第一深情  阅读(7)  评论(0编辑  收藏  举报