24. 走迷宫

走迷宫是一个经典的问题:有一张矩形的地图,地图中有 R*C 个格子,每个格子要么是墙,要么是空地。给定一个起点和一个终点(起点和终点都是空地),问能否从起点走到终点。郭老师按照广度优先搜索的思路,写了如下代码:

define process_cell(r, c):
    if (r, c) is not outside the maze:
        if cell at (r, c) is not a wall:
            if (r, c) is unvisited:
                if treasure is at (r, c), terminate the entire search
                put (r, c) into Q and mark (r, c) as visited

define BFS(startr, startc):
    initialize an empty queue Q
    put (startr, startc) into Q and mark (startr, startc) as visited
    while Q is not empty:
        get (r, c) from the queue
        for each (nr, nc) in (r, c+1), (r-1, c), (r, c-1), (r+1, c):
            process_cell(nr, nc)

其中郭老师使用了循环队列存储待搜索的节点。循环队列 Q 用c语言实现的一个版本如下:

#define K 2000
int q[K];
int head, tail;

void push(int x, int y){
    q[tail] = x;
    tail = (tail + 1) % K;
}

void pop(){
    head = (head + 1) % K;
}

int get_head(){
    return q[head];
}

int empty(){
    if (head == tail) 
        return 1;
    else 
        return 0;
}

int init(){
    head = tail = 0;
}

班级里某些编程高手发现定义的循环队列的最大长度 K 有些小,于是开始搞破坏,决定构造一个地图使得郭老师的程序挂掉,你能得逞吗?(我们认为当队列中的元素个数 >=K 的话就算挂掉。如按照上述代码来实现,最多只能放 K-1 个元素,因为当元素个数等于 K 的时候,head等于tail)

输入

输入包含三个数字R,C,K。R 和 C 分别表示地图中的行数和列数,K 表示循环队列大小。

数据范围,100 ≤ R, C ≤ 1000,2 * min(R, C) ≥ max(R, C)

输出

一个 R*C 的字符矩形,字符 'S' 表示起点,字符 'T' 表示终点,字符 '.' 表示空地,字符 '*' 表示墙。此题开通Special Judge

测试输入关于“测试输入”的帮助期待的输出关于“期待的输出”的帮助时间限制关于“时间限制”的帮助内存限制关于“内存限制”的帮助额外进程关于“{$a} 个额外进程”的帮助
测试用例 1以文本方式显示
  1. 3 3 5↵
以文本方式显示
  1. ...↵
  2. .S.↵
  3. T..↵
1秒64M0

题解:

构造分型图,如下,分上下左右四个方向递归,不过要注意边界条件的设置

图片没找到了,就是一个“H”不断分


//看了讨论区里大佬给的思路,就是打印一个分形图
#include<stdio.h>  
#include<string.h>

char Map[1005][1005] = { '\0' };
void Panting(int S_x, int S_y, int m,int n)
{
	if (m <= 1 && n <= 1)
		return;
	int x1 = S_x - m / 4, x2 = S_x + m / 4, y1 = S_y - n / 4, y2 = S_y + n / 4;
	for (int i = x1; i <= x2; i++)
		Map[i][S_y] = '.';
	for (int j = y1; j <= y2; j++)
	{
		Map[x2][j] = '.';
		Map[x1][j] = '.';
	}
	Panting(x1, y1, m / 2, n / 2);
	Panting(x2, y1, m / 2, n / 2);
	Panting(x1, y2, m / 2, n / 2);
	Panting(x2, y2, m / 2, n / 2);
}
int main()
{
	int C_n, R_m, k;
	scanf("%d %d %d", &R_m, &C_n, &k);
	int S_x = R_m / 2, S_y= C_n / 2;
	if (C_n > 5 && R_m > 5)
	{
		memset(Map, '*', sizeof(Map));
		Panting(S_x, S_y, R_m, C_n);
		Map[S_x][S_y] = 'S';
		Map[R_m - 1][C_n - 1] = 'T';
		for (int i = 0; i<R_m; i++)
		{
			for (int j = 0; j<C_n; j++)
				printf("%c", Map[i][j]);
			printf("\n");
		}
	}
	else
	{
		memset(Map, '.', sizeof(Map));
		Map[S_x][S_y] = 'S';
		Map[R_m - 1][C_n - 1] = 'T';
		for (int i = 0; i<R_m; i++)
		{
			for (int j = 0; j < C_n; j++)
				printf("%c", Map[i][j]);
			printf("\n");
		}
	}

	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值