poj3322 Bloxorz I

大模拟……要加剪枝……

开一个stp数组记录一下到某个格子时某个状态下的最小步骤……不然会MLE+TLE……

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;

const int N = 510;

char mp[N][N];

int n, m, stp[N][N][5];

struct pos {
	int x, y;
} hole, blk[2];

struct state {
	int x, y, turn, dis;
	/*
		turn(1): 竖起来
		X

		turn(2): 向右横着
		XX

		turn(3): 向下竖着
		X
		X
	*/
};

queue<state> q;

void init() {
	blk[0].x = blk[1].x = 0;
	while(q.size()) q.pop();
	memset(stp, 0x3f, sizeof stp);
}

#define inside(x, y) (2 <= x && x <= n - 1 && 2 <= y && y <= m - 1)

int main() {

	#ifndef ONLINE_JUDGE
		freopen("in", "r", stdin);
	#endif

	while(scanf("%d%d", &n, &m) == 2 && (n || m)) {
		init();
		for(int i = 1 ; i <= n ; ++ i) {
			scanf("%s", mp[i] + 1);
			for(int j = 1 ; j <= m ; ++ j) {
				if(mp[i][j] == 'O') {
					hole = (pos) {i, j};
				} else if(mp[i][j] == 'X') {
					if(!blk[0].x) blk[0] = (pos) {i, j};
					else blk[1] = (pos) {i, j};
				}
			}
		}

		if(!blk[1].x)
			q.push((state) {blk[0].x, blk[0].y, 1, 0});
		else if(blk[0].x == blk[1].x) 
			q.push((state) {blk[0].x, min(blk[0].y, blk[1].y), 2, 0});
		else 
			q.push((state) {min(blk[0].x, blk[1].x), blk[0].y, 3, 0});

		while(q.size()) {
			state u = q.front();
			int x = u.x, y = u.y, turn = u.turn, dis = u.dis;
			q.pop();
			if(x == hole.x && y == hole.y && turn == 1) {
				printf("%d\n", dis);
				goto nxt;
			}

			if(stp[x][y][turn] <= dis) continue;

			stp[x][y][turn] = dis;

			if(turn == 1) {
				// X
				if(inside(x - 2, y) && mp[x - 1][y] != '#' && mp[x - 2][y] != '#') {
					q.push((state) {x - 2, y, 3, dis + 1});
				}
				if(inside(x + 2, y) && mp[x + 1][y] != '#' && mp[x + 2][y] != '#') {
					q.push((state) {x + 1, y, 3, dis + 1});
				}
				if(inside(x, y - 2) && mp[x][y - 1] != '#' && mp[x][y - 2] != '#') {
					q.push((state) {x, y - 2, 2, dis + 1});
				}
				if(inside(x, y + 2) && mp[x][y + 1] != '#' && mp[x][y + 2] != '#') {
					q.push((state) {x, y + 1, 2, dis + 1});
				}
			} else if(turn == 2) {
				// XX
				if(inside(x - 1, y) && mp[x - 1][y] != '#' && mp[x - 1][y + 1] != '#') {
					q.push((state) {x - 1, y, 2, dis + 1});
				}
				if(inside(x + 1, y) && mp[x + 1][y] != '#' && mp[x + 1][y + 1] != '#') {
					q.push((state) {x + 1, y, 2, dis + 1});
				}
				if(inside(x, y - 1) && mp[x][y - 1] != '#' && mp[x][y - 1] != 'E') {
					q.push((state) {x, y - 1, 1, dis + 1});
				}
				if(inside(x, y + 2) && mp[x][y + 2] != '#' && mp[x][y + 2] != 'E') {
					q.push((state) {x, y + 2, 1, dis + 1});
				}
			} else if(turn == 3) {
				// X
				// X
				if(inside(x, y - 1) && mp[x][y - 1] != '#' && mp[x + 1][y - 1] != '#') {
					q.push((state) {x, y - 1, 3, dis + 1});
				}
				if(inside(x, y + 1) && mp[x][y + 1] != '#' && mp[x + 1][y + 1] != '#') {
					q.push((state) {x, y + 1, 3, dis + 1});
				}
				if(inside(x - 1, y) && mp[x - 1][y] != '#' && mp[x - 1][y] != 'E') {
					q.push((state) {x - 1, y, 1, dis + 1});
				}
				if(inside(x + 2, y) && mp[x + 2][y] != '#' && mp[x + 2][y] != 'E') {
					q.push((state) {x + 2, y, 1, dis + 1});
				}
			}
		}
		puts("Impossible");
		nxt:;
	}
}

  

posted @ 2017-12-04 17:56  KingSann  阅读(247)  评论(0)    收藏  举报