UVa 705 - Slash Maze

【题译】

通过字符'\'和'/',你可以生成一个小巧的迷宫。迷宫中的路径不会有分叉,因此迷宫中的路径可以形成环,也可以通往迷宫的入口和出口。我们只对环感兴趣。

给你指定一个编程任务,找出迷宫中环的个数,以及所有环当中最长路径的长度。长度通过原文图中所示的灰色方块个数统计求得,在该例子中,最长环的长度为16,共有2个环。

【思路】

由于是倾斜的迷宫(不知道这么说对不对),不能用往常的迷宫遍历来做,需要做一些处理,将斜迷宫转为横竖迷宫,也就是我们熟悉的迷宫。关键就是对字符'/'和字符'\'的处理。字符'\'可表示为

将字符转为3*3的小矩阵,一个圆圈代表迷宫中可以走动的路径,而X标记代表墙壁,不能走到这个位置,对字符'/'的处理也是一样


因此,题目中所给的第一个输入样例可表示为下图


蓝色的圆圈形成环的路径,这样只需沿着上下左右四个方向简单遍历即可。由图中可知共有2个环,最长的环路径包含了48个圆圈,由于圆圈是3*3矩阵内的元素,将48再除回3,可得到最大长度16。


【代码】

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <stack>
#include <queue>
#include <vector>
#include <list>
#include <set>
#include <algorithm>


#define loop_add(i, x1, x2) for (int i = (x1); i <= (x2); i ++)
#define loop_dec(i, x1, x2) for (int i = (x1); i >= (x2); i --)
#define	GetMax(a, b) ((a) > (b))? (a) : (b);
#define	GetMin(a, b) ((a) < (b))? (a) : (b);
#define EPS 1e-
using namespace std;

bool visit[80*3][80*3];// 标记被访问过的位置
bool map[80*3][80*3];// 简化处理后的迷宫
bool isLoop;// 判断深度优先搜索能否形成一个环
int cnt, maxLength, curLength;// 环的个数,环的最大长度,当前遍历得到的长度
int row, col;// 迷宫的行数、列数

int dirx[] = {0, 1, 0, -1};// x方向的搜索
int diry[] = {-1, 0, 1, 0};// y方向的搜索


bool isOut(int x, int y) {
	if (x < 0 || y < 0 || x >= row*3 || y >= col*3)// 是否越界
		return true;
	else
		return false;
}

void dfs(int curx, int cury) {
	visit[curx][cury] = true;// 标记为访问过
	curLength ++;// 当前步长增加1

	loop_add(i, 0, 3) {
		int x = curx+dirx[i];
		int y = cury+diry[i];

		if (isOut(x, y)) {
			isLoop = false;//越界了就不可能形成环
			return;
		}

		if (!visit[x][y] && !map[x][y]) {
			dfs(x, y);// 继续向下一个方向搜索
		}
	}
}

int main() {
	int t = 1;
	while (~scanf("%d%d", &col, &row) && (row || col)) {
		maxLength = 0;
		cnt = 0;
		memset(visit, false, sizeof (visit));
		memset(map, false, sizeof (map)); // map数值为false代表该位置可以通行,否则为障碍物

		for (int i = 0; i < row*3; i += 3) {
			getchar();
			for (int j = 0; j < col*3; j += 3) {
				char ch = getchar();
				if (ch == '\\') // 输入了'\'的符号
					map[i][j] = map[i+1][j+1] = map[i+2][j+2] = true;
				else if (ch == '/') // 输入了'/'的符号
					map[i][j+2] = map[i+1][j+1] = map[i+2][j] = true;
			}
		}

		loop_add(i, 0, 3*row-1) {
			loop_add(j, 0, 3*col-1) {
				if (!visit[i][j] && !map[i][j]) {
					curLength = 0;
					isLoop = true;

					dfs(i, j);//从坐标(i, j)开始深度优先搜索

					if (isLoop) {
						maxLength = GetMax(maxLength, curLength);
						cnt ++;
					}
				}
			}
		}

		printf("Maze #%d:\n", t ++);
		if (cnt > 0)
			printf("%d Cycles; the longest has length %d.\n\n", cnt, maxLength/3);
		else
			printf("There are no cycles.\n\n");
	}
	return 0;
}






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值