洛谷 P1825 [USACO11OPEN]Corn Maze S(bfs)

题目传送

1.这仅仅是一道加了传送门的bfs
2.仅仅加了一个传送门,就卡了我一下午
3.门存在不成对的情况。。。。。。。。。

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
const int maxn = 305;
const int inf = 0x3f3f3f3f;
const int dx[] = { 0,1,0,-1 };
const int dy[] = { 1,0,-1,0 };

struct node {
	int x, y;
	node(int x = 0, int y = 0) :x(x), y(y) {}
}cs[30][2];  //记录传送门

int n, m, qx, qy, zx, zy, fx, fy;
int map[maxn][maxn];
int step[maxn][maxn];
queue<node> q;

//找到另一个传送门
void ff(int x, int y)
{
	if (cs[map[x][y] - 'A'][0].x != x || cs[map[x][y] - 'A'][0].y != y) {
		fx = cs[map[x][y] - 'A'][0].x;
		fy = cs[map[x][y] - 'A'][0].y;
	}
	else {
		fx = cs[map[x][y] - 'A'][1].x;
		fy = cs[map[x][y] - 'A'][1].y;
	}
}

//判断传送门是否成对
bool cheak(int x, int y)
{
	return cs[map[x][y] - 'A'][1].x != 0;
}

void bfs()
{
	memset(step, inf, sizeof(step));
	step[qx][qy] = 0;
	q.push(node(qx, qy));
	while (q.size()) {
		int x = q.front().x;
		int y = q.front().y;
		q.pop();
		for (int i = 0; i < 4; i++) {
			int xx = x + dx[i];
			int yy = y + dy[i];
			if (!map[xx][yy]) continue;
			//传送
			if (map[xx][yy] >= 'A' && map[xx][yy] <= 'Z' && cheak(xx, yy)) {
				ff(xx, yy);
				if (step[fx][fy] > step[x][y] + 1) {
					step[fx][fy] = step[x][y] + 1;
					q.push(node(fx, fy));
				}
			}
			//用脚走
			else if (step[xx][yy] > step[x][y] + 1) {
				step[xx][yy] = step[x][y] + 1;
				q.push(node(xx, yy));
			}
		}
	}
}

int main(void)
{
	//freopen("D:\\in.txt", "r", stdin);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			char ch;
			cin >> ch;
			if (ch == '.') map[i][j] = 1;
			else if (ch == '#') map[i][j] = 0;
			else if (ch == '@') {
				qx = i;
				qy = j;
				map[i][j] = 1;
			}
			else if (ch == '=') {
				zx = i;
				zy = j;
				map[i][j] = 1;
			}
			else if (ch >= 'A' && ch <= 'Z') {
				//记录传送门
				if (cs[ch - 'A'][0].x == 0) {
					cs[ch - 'A'][0].x = i;
					cs[ch - 'A'][0].y = j;
				}
				else {
					cs[ch - 'A'][1].x = i;
					cs[ch - 'A'][1].y = j;
				}
				map[i][j] = ch;
			}
		}
	}
	bfs();
	cout << step[zx][zy] << endl;
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值