Bloxorz POJ3322

Bloxorz POJ3322

思路

题干在这:POJ3322
学习广搜,抄的算法竞赛进阶指南的示例代码

ac代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
struct rec {
	int x, y, lie;
};
char s[510][510];
rec st, ed;
int n, m, d[510][510][3];
queue<rec> q;
const int dx[4] = { 0,0,-1,1 }, dy[4] = { -1,1,0,0 };
bool valid(int x, int y) {
	return x >= 1 && y >= 1 && x <= n && y <= m;
}
void parse_st_ed() {
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			if (s[i][j] == 'O') {
				ed.x = i;
				ed.y = j;
				ed.lie = 0;
				s[i][j] = '.';
			}
			else if (s[i][j] == 'X') {
				for (int k = 0; k < 3; k++) {
					int x = i + dx[k], y = j + dy[k];
					if (valid(x, y) && s[x][y] == 'X') {
						st.x = min(i, x);
						st.y = min(j, y);
						st.lie = k < 2 ? 1 : 2;
						s[i][j] = s[x][y] = '.';
						break;
					}
				}
				if (s[i][j] == 'X') {
					st.x = i;
					st.y = j;
					st.lie = 0;
				}
			}
		}
	}
}
bool valid2(rec next) {
	if (!valid(next.x, next.y))
		return 0;
	if (s[next.x][next.y] == '#')
		return 0;
	if (next.lie == 0 && s[next.x][next.y] != '.')
		return 0;
	if (next.lie == 1 && s[next.x][next.y + 1] == '#')
		return 0;
	if (next.lie == 2 && s[next.x + 1][next.y] == '#')
		return 0;
	return 1;
}
const int next_x[3][4] = { {0,0,-2,1},{0,0,-1,1},{0,0,-1,2} };
const int next_y[3][4] = { {-2,1,0,0},{-1,2,0,0},{-1,1,0,0} };
const int next_lie[3][4] = { {1,1,2,2},{0,0,1,1},{2,2,0,0} };
int bfs() {
	memset(d, -1, sizeof(d));
	while (q.size())
		q.pop();
	d[st.x][st.y][st.lie] = 0;
	q.push(st);
	while (q.size()) {
		rec now = q.front();
		q.pop();
		for (int i = 0; i < 4; i++) {
			rec next;
			next.x = now.x + next_x[now.lie][i];
			next.y = now.y + next_y[now.lie][i];
			next.lie = next_lie[now.lie][i];
			if (!valid2(next))
				continue;
			if (d[next.x][next.y][next.lie] == -1) {
				d[next.x][next.y][next.lie] = d[now.x][now.y][now.lie] + 1;
				q.push(next);
				if (next.x == ed.x && next.y == ed.y && next.lie == ed.lie)
					return d[next.x][next.y][next.lie];
			}
		}
	}
	return -1;
}
int main() {
	while (cin >> n >> m && n) {
		//getchar();
		for (int i = 1; i <= n; i++) {
			scanf_s("%s", s[i] + 1,509);
		}
		parse_st_ed();
		int ans = bfs();
		if (ans == -1) {
			puts("Impossible");
		}
		else
			cout << ans << endl;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值