ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【ybtoj】【BFS】【例题3】立体推箱子

2021-01-09 09:32:30  阅读:222  来源: 互联网

标签:yy return int ybtoj tt st BFS xx 例题


【例题3】立体推箱子


Link

传送门
题目


解题思路

记录状态时将坐标和木块状态一起记录 ( q [ x ] [ y ] [ t ] ) (q[x][y][t]) (q[x][y][t])
在这里插入图片描述
对于2状态,坐标默认是下面那一块
对于3状态,坐标默认是右边那一块
有几个需要注意的旋转时坐标的改变
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


Code

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

const int xw[4][5] = {{}, {-1, 0, 2}, {-2, 0, 1}, {-1, 0, 1}};//把坐标的改变预处理出来
const int yw[4][5] = {{}, {0, 2, 0, -1}, {0, 1, 0, -1}, {0, 1, 0, -2}};
const int tw[4][5] = {{}, {2, 3, 2, 3}, {1, 2, 1, 2}, {3, 1, 3, 1}};
int n, m, s[510][510][5], q[750100][3], h, t, v[510][510][5];
int sx, sy, st, ex, ey, et, ans;
char a[510][510];

void initial() {
	st = 0;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			if (a[i][j] == 'X' && !st) {
				if (a[i + 1][j] == 'X')//状态2
					sx = i + 1, sy = j, st = 2;
				 else
				if (a[i][j + 1] == 'X')//状态3
					sx = i, sy = j + 1, st = 3;
				 else
				sx = i, sy = j, st = 1;//只有一个‘X’是状态1
			}
			if (a[i][j] == 'O')
				ex = i, ey = j, et = 1;
		}
}

bool check(int x, int y, int t) {
	if (x < 0 || x > n || y < 0 || y > m)
		return 0;
	if (t == 1) {
		if (a[x][y] == 'E' || a[x][y] == '#')//不可以立在易碎地面上
			return 0;
	}
	if (t == 2) {
		if (a[x][y] == '#' || a[x - 1][y] == '#')
			return 0;
	}
	if (t == 3) {
		if (a[x][y] == '#' || a[x][y - 1] == '#')
			return 0;
	}
	return 1;
}

bool BFS() {
	h = t = s[sx][sy][st] = 0;
	q[++t][0] = sx, q[t][1] = sy, q[t][2] = st;
	while (h++ < t) {
		for (int i = 0; i < 4; i++) {
			int xx = q[h][0] + xw[q[h][2]][i];
			int yy = q[h][1] + yw[q[h][2]][i];
			int tt = tw[q[h][2]][i];
			if (check(xx, yy, tt) && //判断当前的(xx, yy, tt)可不可行
				!v[xx][yy][tt]) {//判断(xx, yy, tt)走没走过
				s[xx][yy][tt] = s[q[h][0]][q[h][1]][q[h][2]] + 1;//记录步数
				v[xx][yy][tt] = 1, q[++t][0] = xx, q[t][1] = yy, q[t][2] = tt;
				if (xx == ex && yy == ey && tt == et) {//走到‘O’上
					printf("%d\n", s[ex][ey][et]);
					return 0;
				}
			}
		}
	}
	return 1;
}

int main() {
	scanf("%d%d", &n, &m);
	while (n && m) {
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++)
				cin>>a[i][j];
		initial();//预处理
		if (BFS())
			printf ("Impossible\n");
		//*****************************************
		ans = 0;
		memset(v, 0, sizeof(v));
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++)
				a[i][j] = '\0';
		//清空*************************************
		scanf("%d%d", &n, &m);
	}
}

标签:yy,return,int,ybtoj,tt,st,BFS,xx,例题
来源: https://blog.csdn.net/qq_39940018/article/details/112387426

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有