迷宫问题(代写)

In this final project, you are required to design and implement a algorithm to solve the Maze Problem. In detail, you must complete following tasks:

1.use a text file to store a 2-D array, read a 2-D array from file, and construct a Maze with this 2-D array. In the 2-D array, “0” means no obstacle, “1” means obstacle.

2.Print out the Maze constructed in (1) with “□” and “○”, “□” for “1” and “○” for “0”;

3.Write a program to find a path from start point to end point. You can define the start point and end point by yourself.

4.Print out the point sequence in the path;

5.Print out the path with “☆”

Given a maze diagram with M rows and N columns, where "0" represents a passable path and "1" represents an obstacle that is impassable.In the maze, you are only allowed to walk in horizontal or upper and lower paths. You cannot repeat the position.

Each maze is guaranteed to have at most one shortest path.

Please print this shortest path or "NO FOUND" if NO path exists

 

  1. Algorithm Design

首先定义两个二维数组一个用于获取储存的迷宫一个用于临时的迷宫定义一个方向数组之后用for循环来模拟上下左右走q为一个数组来模拟队列p[]记录路径

每次bfs进行广搜进行遍历所有的点然后存到q里面直到找到结束的点然后从队列里面从头开始输出存的地址就是路径如果跑遍所有的答案没找到路径就输出没有答案。

  1. Algorithm Implement

 

Bfs的具体实现是首先我定义了一个头指针尾指针和数组用来模拟队列然后将开始点存到队列中当队列不为空的时候就用移动数组模拟上下左右的如果可以走的就加进队列中并把上一个点记录进路径队列方便输出直到找到终点结束。

  1. Results

通过bfs和答案队列记录就可以判断迷宫是否有解和路径的输出通过答案队列的反向输出即可输出出我之前走过的路然后用数组标记一下最后输出出所有的地图包括标记就能输出出来答案。

  1. Conclusion

通过学习我了解了一些bfs算法和一些模拟队列的方法,对于一些函数和数据结构有了更加深刻的了解,希望在以后能学会更多更加好的算法来解决日常生活中的问题,为自己的未来努力加油!

 

#include <cstdio>
#include <windows.h>
using namespace std;

//maxn为数组模拟队列的最大长度
const int maxn = 3e5 + 3;
//迷宫大小 m * n
int m, n, cnt;
//maze存储迷宫的数组 t_m临时求解迷宫
char maze[503][503], t_m[503][503];
//方向数组,广搜顺序右下左上
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
//迷宫结构体,xy存储坐标,f为父节点
//e迷宫终点,t临时坐标,q[]为模拟队列,p[]记录路径
int start_xx, start_yy;
struct mi {
    int x, y, f;
} e, t, q[maxn], p[maxn];
//设置输出迷宫路径时的颜色显示
void input_maze() {
    printf("***欢迎使用迷宫求解程序***\n\n");
    printf("->请输入迷宫的大小:\n");
    scanf("%d %d", &m, &n);
    printf("->请输入迷宫地图:\n");
    for(int i = 0;i < m;++i) {
    	getchar();
		for (int j = 0; j < n; ++j) {
            scanf("%c", &maze[i][j]);
		}
	}
    printf("请输入开始坐标格式x y:");
    int x, y;
    scanf("%d%d", &x, &y);
    maze[x][y] = 'S';start_xx = x, start_yy = y;
    printf("请输入结束坐标格式x y:");
    scanf("%d%d", &x, &y);
    maze[x][y] = 'E';
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            //复制迷宫到临时迷宫
            t_m[i][j] = maze[i][j];
            //寻找迷宫起点和终点
            if (maze[i][j] == 'S') {
                q[1].x = i;
                q[1].y = j;
                q[1].f = -1;
            } else if (maze[i][j] == 'E') {
                e.x = i;
                e.y = j;
            }
        }
    }
    printf("->迷宫输入完成\n");
}
//判断广搜是否越出迷宫
bool range(int x, int y) {
    //越界返回true,否则false
    if (x >= 0 && x < m && y >= 0 && y < n)
        return false;
    return true;
}
//递归记录迷宫解的路径
void rec_path(int pos) {
    //递归至起点
    if (q[pos].f == -1) {
        p[cnt].x = q[pos].x + 1;
        p[cnt].y = q[pos].y + 1;
        cnt++;
        return ;
    }
    //继续寻找当前节点的父节点
    rec_path(q[pos].f);
    maze[q[pos].x][q[pos].y] = '*';
    p[cnt].x = q[pos].x + 1;
    p[cnt].y = q[pos].y + 1;
    cnt++;
}
//广搜求解迷宫,数组模拟队列
int BFS() {
    printf("->迷宫求解中...\n");
    //初始化队列的头指针和尾指针
    int head = 1, tail = 2;
    //队列不为空则继续广搜
    while (head < tail) {
        //找到迷宫终点
        if (q[head].x == e.x && q[head].y == e.y)
            return head;
        //枚举迷宫的四个方向
        for (int i = 0; i < 4; ++i) {
            t.x = q[head].x + dir[i][0];
            t.y = q[head].y + dir[i][1];
            //若越界或为墙则进行下一个方向
            if (range(t.x, t.y) || t_m[t.x][t.y] == '1')
                continue;
            //标记当前位置已入队
            t_m[t.x][t.y] = '1';
            //将新的节点入队
            q[tail].x = t.x;
            q[tail].y = t.y;
            q[tail].f = head;
            //队尾加一
            tail++;
        }
        //队首出队
        head++;
    }
    return 0;
}
//打印迷宫解的路径
void print_path() {
    printf("->迷宫解的路径:\n");
    int t = n / 8, i = 0;
    if (t == 0)
        t = n;
    while (i < cnt - 1) {
        printf("%2d %2d-> ", p[i].x, p[i].y);
        i++;
        if (i % t == 0)
            printf("\n");
    }
    printf("%2d %2d\n", p[cnt - 1].x, p[cnt - 1].y);
}
//打印迷宫
void print_maze() {
    printf("->迷宫的解:\n");
    maze[e.x][e.y] = 'E';
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            if (maze[i][j] == '*') {
                maze[i][j] = ' ';
               // color(207);
                //printf("%c", maze[i][j]);
                printf("☆");
                //color();
            }
			else if(i == start_xx && j == start_yy) {
				printf("△");
			} 
			else {
            	if(maze[i][j] == '1') {
            		printf("□");
				}
				else if(maze[i][j] == '0') {
					printf("○");
				}
				else {
					printf("●");
				}
                //printf("%c", maze[i][j]);
                //printf("%c", maze[i][j]);
            }
        }
        printf("\n");
    }
}
//输出迷宫的解
void print() {
    int sol = BFS(), sel;
    if (sol) {
        printf("->迷宫有解\n");
        cnt = 0;
        rec_path(sol);
        printf("-> 1.输出路径\n");
        printf("-> 2.输出迷宫\n");
        printf("-> 3.输出路径及迷宫\n");
        scanf("%d", &sel);
        switch (sel) {
            case 3:
                print_path();
                print_maze();
                break;
            case 2:
                print_maze();
                break;
            case 1:
                print_path();
                break;
            default :
                printf("->输入有误\n");
        }
    } else {
        printf("->NO FOUND\n");
    }
}
//运行函数
void run() {
    int flag = 1;
    while (flag) {
        system("cls");
        input_maze();
        print();
        printf("->输入0结束,其它数字继续:\n");
        scanf("%d", &flag);
    }
}
//主函数
int main () {
    run();
    return 0;
}
//测试数据
/*
17 35
11111111111111111111111111111111111
10000000000000000100000000000000001
10111101111111111101111111111111101
10100000000000000000000000000000101
10101111111111111111111111111111101
10101000000000000100000000000000101
10101011101111111111101111111010101
10101010000000001111101000001010001
11101010111111101000001011101011111
10101010000100001111101000100010001
10101011111111111111111111111110101
10100000000000000000000000000010100
10111111111111111011111111111110101
10000000000000000010000000000000101
10111111111111111111111111111111101
10000000000000000000000000000000001
11111111111111111111111111111111111
9 18
10 25
3
5 5
01111
11111
11111
11111
11110
1 1
5 5
*/

效果

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-lyslyslys

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值