POJ 3322 Bloxorz I

 

目录

一.题目简介

可以先玩一下这个游戏

点击打开链接

 二.题解

三.代码

谢谢!


一.题目简介

可以先玩一下这个游戏

点击打开链接

 二.题解

这道题目就是波尔皮,很简单,就是爆搜一通,BFS直接暴力物体从起点到终点的全过程。

但是就一个难点,对于每一个状态的判重和转移。

首先,我们要明白有三种情况,分别是上面图片中的三种情况,我分别称其为:立(0)、横(2)、竖(1)。

然后由于有些状态的物体是躺着的,占据两个单位格子,我们可以强制把这种状态归为一个单位格子,并且只标记一个格子,我是横着就标记左面的格子,竖着就标记上面的格子,立着就不用说了,所以可以用一个三维的标记数组:第一维: 表示状态;第二维:第几行;第三维:第几列。

最后就是写方向函数,同样可以定义一个三维的dir数组:dir[3][4][3]。表示:三种状态,每种状态有四种转移方式,这四种每种有三个变量:x坐标的转移,y坐标的转移,转移之后的状态。我定义了两个dir,第一个是转移要标记的格子,第二个是转移不标记的格子,因为我要判断它整个物体的放法是否合法。注意转移的时候的判断有点繁琐。

int dir1[3][4][3] = {//负责要标记的格子的转移
	{{1, 0, 1}, {-2, 0, 1}, {0, -2, 2}, {0, 1, 2}},
	{{2, 0, 0}, {-1, 0, 0}, {0, -1, 1}, {0, 1, 1}},
	{{-1, 0, 2}, {1, 0, 2}, {0, -1, 0}, {0, 2, 0}},
};
int dir2[3][4][3] = {//负责不标记的格子的转移
	{{2, 0, 1}, {-1, 0, 1}, {0, -1, 2}, {0, 2, 2}},
	{{2, 0, 0}, {-1, 0, 0}, {1, -1, 1}, {1, 1, 1}},
	{{-1, 1, 2}, {1, 1, 2}, {0, -1, 0}, {0, 2, 0}},
};

三.代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
int r, c, sx[3], sy[3], k;
bool flag, vis[3][505][505];
int dir1[3][4][3] = {
	{{1, 0, 1}, {-2, 0, 1}, {0, -2, 2}, {0, 1, 2}},
	{{2, 0, 0}, {-1, 0, 0}, {0, -1, 1}, {0, 1, 1}},
	{{-1, 0, 2}, {1, 0, 2}, {0, -1, 0}, {0, 2, 0}},
};
int dir2[3][4][3] = {
	{{2, 0, 1}, {-1, 0, 1}, {0, -1, 2}, {0, 2, 2}},
	{{2, 0, 0}, {-1, 0, 0}, {1, -1, 1}, {1, 1, 1}},
	{{-1, 1, 2}, {1, 1, 2}, {0, -1, 0}, {0, 2, 0}},
};
char G[505][505];
struct node {
	int x, y, d, step;
};
bool pd (int tox, int toy){
	if (tox < 1 || tox > r || toy < 1 || toy > c || G[tox][toy] == '#')
		return 0;
	return 1;
}
void BFS (){
	queue <node> f;
	node t1, t2;
	if (k == 1)//特判物体的起始状态
		t1.d = 0;
	else
		if (sx[1] == sx[2] - 1)
			t1.d = 1;
		else
			t1.d = 2;
	t1.x = sx[1], t1.y = sy[1], t1.step = 0;
	vis[t1.d][t1.x][t1.y] = 1;
	f.push (t1);
	while (! f.empty ()){
		t1 = f.front ();
		f.pop ();
		if (t1.d == 0 && G[t1.x][t1.y] == 'O'){
			printf ("%d\n", t1.step);
			flag = 1;
			return ;
		}
		for (int i = 0; i < 4; i ++){
			int tox1 = dir1[t1.d][i][0] + t1.x;
			int toy1 = dir1[t1.d][i][1] + t1.y;
			int tox2 = dir2[t1.d][i][0] + t1.x;
			int toy2 = dir2[t1.d][i][1] + t1.y;
			if (dir1[t1.d][i][2] == 0 && G[tox1][toy1] == 'E')
				continue;
			if (pd (tox1, toy1) && pd (tox2, toy2) && ! vis[dir1[t1.d][i][2]][tox1][toy1]){
				t2.x = tox1, t2.y = toy1, t2.step = t1.step + 1;
				t2.d = dir1[t1.d][i][2];
				vis[t2.d][t2.x][t2.y] = 1;
				f.push (t2);
			}
		}
	}
}
int main (){
	while (scanf ("%d %d", &r, &c) && r != 0 && c != 0){
		memset (vis, 0, sizeof (vis));
		flag = 0;
		k = 0;
		for (int i = 1; i <= r; i ++){
			getchar ();
			for (int j = 1; j <= c; j ++){
				scanf ("%c", &G[i][j]);
				if (G[i][j] == 'X')
					sx[++ k] = i, sy[k] = j;
			}
		}
		BFS ();
		if (! flag)
			printf ("Impossible\n");
	}
	return 0;
}

谢谢!

发布了61 篇原创文章 · 获赞 32 · 访问量 8361

猜你喜欢

转载自blog.csdn.net/weixin_43908980/article/details/90235628