NC15136 迷宫




一开始把题意理解错了,结果样例都没过
总而言之,这道题要分情况讨论
1.直接从S走到E
2.先从S走到K,再从K走到E

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int maxn = 505;

bool key;
int dis[maxn][maxn];
char map[maxn][maxn];
int dir[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };
int h, w, startx, starty, endx, endy, keyx, keyy, doorx, doory, ansS_E, ansS_K_E;
struct node {
	int x, y;
};
queue<node> q;

void p() {
	cout << endl;
	cout << "**" << endl;
}

bool inmap(int x, int y) {
	if (x <= 1 || x >= h) return 0;
	if (y <= 1 || y >= w) return 0;
	return 1;
}

int dfsS_E() {//直接从S走到E
	dis[startx][starty] = 0;
	q.push({ startx,starty });
	while (!q.empty()) {
		node tmp = q.front();
		q.pop();
		for (int i = 0; i < 4; i++) {
			int tx = tmp.x + dir[i][0];
			int ty = tmp.y + dir[i][1];
			if (inmap(tx, ty) && dis[tx][ty] == -1) {
				if (map[tx][ty] != 'D' && map[tx][ty] != 'W') {
					dis[tx][ty] = dis[tmp.x][tmp.y] + 1;
					q.push({ tx,ty });
				}
			}
		}
	}
	if (dis[endx][endy] == -1) return 0;
	return dis[endx][endy];
}

int dfsS_K_E() {//先从S到K,再到E
	dis[startx][starty] = 0;
	q.push({ startx,starty });
	while (!q.empty()) {
		node tmp = q.front();
		q.pop();
		for (int i = 0; i < 4; i++) {
			int tx = tmp.x + dir[i][0];
			int ty = tmp.y + dir[i][1];
			if (inmap(tx, ty) && dis[tx][ty] == -1) {
				if (map[tx][ty] != 'D' && map[tx][ty] != 'W') {
					dis[tx][ty] = dis[tmp.x][tmp.y] + 1;
					q.push({ tx,ty });
				}
			}
		}
	}
	if (dis[keyx][keyy] == -1) return 0;
	int ansS_K = dis[keyx][keyy];
	memset(dis, -1, sizeof(dis));
	dis[keyx][keyy] = 0;
	q.push({ keyx,keyy });
	while (!q.empty()) {
		node tmp = q.front();
		q.pop();
		for (int i = 0; i < 4; i++) {
			int tx = tmp.x + dir[i][0];
			int ty = tmp.y + dir[i][1];
			if (inmap(tx, ty) && dis[tx][ty] == -1) {
				if (map[tx][ty] != 'W') {
					dis[tx][ty] = dis[tmp.x][tmp.y] + 1;
					q.push({ tx,ty });
				}
			}
		}
	}
	if (dis[endx][endy] == -1) return 0;
	int ansK_E = dis[endx][endy];
	return ansS_K + ansK_E;
}

int main() {
	cin >> h >> w;
	for (int i = 1; i <= h; i++) {
		for (int j = 1; j <= w; j++) {
			cin >> map[i][j];
			if (map[i][j] == 'S') { startx = i; starty = j; }
			if (map[i][j] == 'E') { endx = i; endy = j; }
			if (map[i][j] == 'K') { keyx = i; keyy = j; }
			if (map[i][j] == 'D') { doorx = i; doory = j; }
		}
	}
	memset(dis, -1, sizeof(dis));
	ansS_E = dfsS_E();
	memset(dis, -1, sizeof(dis));
	ansS_K_E = dfsS_K_E();
	if (ansS_E != 0 && ansS_K_E != 0)
		cout << min(ansS_E, ansS_K_E);
	else if (ansS_E == 0 && ansS_K_E != 0)
		cout << ansS_K_E << endl;
	else if (ansS_E != 0 && ansS_K_E == 0)
		cout << ansS_E << endl;
	else if (ansS_E == 0 && ansS_K_E == 0)
		cout << "-1" << endl;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值