poj 2920 Mine Map【BFS】


Mine Map
Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 1023 Accepted: 493

题目大意:

        给一个n*n的金库,金库中有地雷‘*’和空格'?',现在你从金库中间出发,刚刚开始时,【遍历当前格子周围8个格子,如果周围8个格子有一个地雷,则把当前格子标记为 ‘ # ’,如果没有,你可以移动到当前格子的周围8个格子中的任意一个格子,且把当前格子标记为  ‘ . ’ 】然后重复【】中的步骤,直到把所有能走的格子都走过为止。

分析:

        刚刚开始时,把map[][]数组初始化为‘?’,【注意,是8个方向都可以走】。

        在走的过程中,遇到‘.’或'#'时【这些是已走过的标记】,就不要再走了【浪费时间嘛】,

已Accept代码【C++提交】

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

char map[301][301];
int dx[] = {0, 0, 1, -1, 1, 1, -1, -1};//注意8个方向 
int dy[] = {-1, 1, 0, 0, 1, -1, 1, -1};
int n, m;
int r, c;
int x, y;

struct Node {
	int x, y;
	Node () {}
	Node (int x, int y) : x(x), y(y) {}
};

bool Decide(int a, int b) {
	for(int i = 0; i < 8; i++) {
		int kx = a + dx[i];
		int ky = b + dy[i];
		if(kx >= 1 && kx <= n && ky >= 1 && ky <= n && map[kx][ky] == '*')//是否越界 
			return true;
	}
	return false;
}

void BFS() {
	queue <Node> Q;
	while(!Q.empty())
		Q.pop();
	if(Decide(x, y))
		map[x][y] = '#';
	else
		map[x][y] = '.';
	if(map[x][y] == '.')
		Q.push(Node(x, y));
	while(!Q.empty()) {
		Node k = Q.front();
		Q.pop();
		int nx = k.x;
		int ny = k.y;
		for(int j = 0; j < 8; j++) {
			int cx = nx + dx[j];
			int cy = ny + dy[j];
			if(cx >= 1 && cx <= n && cy >= 1 && cy <= n && map[cx][cy] == '?') {
				if(Decide(cx, cy))
					map[cx][cy] = '#';
				else
					map[cx][cy] = '.';
				if(map[cx][cy] == '.')//周围为则入队 
					Q.push(Node(cx, cy));
			}
		}
	}
}

int main() {
	int T, K = 1;
	scanf("%d", &T);
	while(T--) {
		scanf("%d%d", &n, &m);
		for(int i = 1; i <= n; i++)
			for(int j = 1; j <= n; j++)
				map[i][j] = '?';
		for(int i = 1; i <= m; i++) {
			scanf("%d%d", &r, &c);
			map[r][c] = '*';
		}
		x = y = (n + 1) / 2;
		BFS();
		printf("Scenario #%d:\n", K++);
		for(int i = 1; i <= n; i++) {
			for(int j = 1; j <= n; j++) {
				printf("%c", map[i][j]);
			}
			printf("\n");
		}
		printf("\n");//注意 输出 格式 
	}
	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值