迷宫求解

来源:互联网 发布:美国人学编程难吗 编辑:程序博客网 时间:2024/05/19 20:59
#include<iostream>
#include<stack>
#include<fstream>

using namespace std;



struct PosType{         //申明一个位置结构体    
    int col;            //横坐标
    int row;            //纵坐标
    bool flag;
};
static int c[10][10];
void InitFlagMap(char **M){
    int i, j;
    for (i = 0; i<10; i++)
        for (j = 0; j<10; j++)
            c[i][j] = M[i][j] - 48;     //把char类型转化为int类型减去48.

}

//全局数组,记录走过的位置坐标,如果走过,则将所对应坐标的值赋1.实属下策。

typedef struct{               //书上要求要有的结构体,
    int ord;                    //记录路径上的序号
    PosType state;              //上面所写的结构体类型
    int direction;              //方向1 2 3 4代表上下左右
}SElemType;

/*设当前位置的初值为入口位置,
while(栈非空)
if(当前位置可通){
将给元素入栈
如果是结束位置,则结束该函数
否则切换到当前位置的东临位置
}
else{
若栈非空且当前位置有其他方向未经探索
则设定新的当前位置为沿栈顶元素顺时针方向的下一相邻块
若栈不空且栈顶元素相邻快都不通{
则删除栈顶元素
若栈不空,则重新测试下一个栈顶元素,
直至找到下一个可通的相邻块至出口位置或者栈空
}
}
*/
bool Pass(PosType x){        //书上要求的函数,判断是否可以往下运行
    if (x.flag == 1)
        if (c[x.row++][x.col] == 1 || c[x.row--][x.col] == 1 || c[x.row][x.col++] == 1 || c[x.row][x.col--] == 1)//如果此坐标没有走过并且标记值为1 可以通过,否则,通不过
            return  true;
        else
            return false;
    else
        return false;
}

void MarkPoint(char** M, PosType& x){             //通过二维数组标记走过的路
    M[x.row][x.col] = '1';                       //将返回的路重新赋值为0.
    c[x.row][x.col] = 2;
    x.flag = 0;
}

void FootPrint(char** M, PosType& curpos){       //在地图上留下走过的痕迹
    M[curpos.row][curpos.col] = '*';              //用*表示
    c[curpos.row][curpos.col] = 2;                //标记走过的路,感觉和上面的标记没有矛盾,所以不用管
    curpos.flag = 0;
}

PosType  NextPos(char** M, PosType x, int D){             //寻找下一坐标位置
    switch (D)
    {
    case 1:  x.col++;
        x.flag = 1;
        if (M[x.row][x.col] == '0' || c[x.row][x.col] == 2) {
            x.col--;
            x.flag = 0;
        }
        break;
    case 2:  x.row++;
        x.flag = 1;
        if (M[x.row][x.col] == '0' || c[x.row][x.col] == 2) {
            x.row--;
            x.flag = 0;
        }
        break;
    case 3:  x.row--;
        x.flag = 1;//横坐标减1,相当于向左移                                      
        if (M[x.row][x.col] == '0' || c[x.row][x.col] == 2)  {     //如果下一坐标位置的值为1 或者坐标已经走过,
            x.row++;
            x.flag = 0;//则回到原来的点
        }
        break;
    case 4:   x.col--;
        x.flag = 1;
        if (M[x.row][x.col] == '0' || c[x.row][x.col] == 2) {
            x.col++;
            x.flag = 0;
        }
        break;
    default:
        break;
    }
    return x;
}

bool Maze(char** T, PosType &start, PosType &end){
    PosType  curpos;                   //当前位置
    int curstep = 1;                      //第一步为1.
    SElemType  e;
    curpos = start;                        //把第一个位置的坐标给当前位置
    stack<SElemType> S;                   //申明一个栈,存储上面的结构体类型
    do{
        if (Pass(curpos)){                   //Pass函数,检查能否通过
            FootPrint(T, curpos);               //留下走过的路径
            e.ord = curstep;
            e.state = curpos;
            e.direction = 1;
            S.push(e);                       //把保存在结构体中的内容入栈
            if (curpos.col == end.col && curpos.row == end.row)      //如果坐标等于终点坐标
                return true;                                  //返回 有路
            curpos = NextPos(T, curpos, 1);                  //寻找下一个点
            curstep++;                                        //序号加1
        }
        else{                                             //如果路不同,按照下面的程序运行,和书上一样。
            if (!S.empty()){
                e = S.top();
                S.pop();
                while (e.direction == 4 && !S.empty()){
                    MarkPoint(T, e.state);
                    e = S.top();
                    S.pop();
                }
                if (e.direction <= 4){
                    e.direction++;
                    S.push(e);
                    curpos = NextPos(T, e.state, e.direction);
                }

            }
        }
    } while (!S.empty());
    return false;

}

int main(){
    char **M = new char*[10];
    int i = 10, j = 10;
    for (i = 0; i < 10; i++){
        M[i] = new char[10];
    }
    ifstream fin;
    fin.open("D:\\文档\\vsdocument\\migong.txt", ios::in);             //这里是你存放文件迷宫图的地方。
    if (!fin){
        cout << "调用内存失败!";
        exit(1);
    }
    for (int t = 0; t < i; t++)
        for (int k = 0; k < j; k++)
            fin >> M[t][k];
    InitFlagMap(M);
    PosType start, end;
    start.col = 1, start.row = 1, start.flag = 1;
    end.col = 8, end.row = 8, end.flag = 1;
    if (Maze(M, start, end))
    {
        for (int i = 0; i < 10; i++){
            for (int j = 0; j < 10; j++)
                cout << M[i][j] << " ";
            cout << endl;
        }
    }
    system("pause");
    return 0;

}



D:\\文档\\vsdocument\\migong.txt位置下的迷宫图(0表示墙,1表示路)

0000000000
0110001110
0111111000
0011010010
0111111110
0010101010
0111101110
0011110110
0011111010
0000000000

运行结果




虽然值寻找到一条路径,但是当时是根据题目给出的规范来写的。小伙伴们可以在这个基础上再进行更改,有问题私信哦。


0 0
原创粉丝点击