迷宮問題——回溯法解


題目描述


    迷宮是一個二維矩陣,其中1爲牆,0爲路,入口在第一列,出口在最後一列。
    要求從入口開始,從出口結束,按照 上,下,左,右 的順序來搜索路徑.


輸入


    第一行輸入迷宮大小N
    第二行輸入入口座標
    接下來n行輸入完整迷宮


輸出


    輸出完整棋盤,所有解法,走過的路用6表示。


樣例輸入


 8 
 0 7
 1 1 1 1 1 1 1 1
 1 0 1 1 0 0 0 0
 1 0 1 0 0 1 0 1
 1 1 0 0 1 0 1 1
 1 0 0 1 0 0 0 1
 1 0 0 0 0 1 1 1
 1 0 1 0 0 1 0 1
 0 0 1 0 0 0 1 1
 1 1 1 1 0 0 0 1
 1 1 1 1 1 1 1 1 

樣例輸出


 1 1 1 1 1 1 1 1
 1 0 1 1 6 6 6 6
 1 0 1 6 6 1 0 1
 1 1 6 6 1 0 1 1
 1 6 6 1 0 0 0 1
 1 6 0 0 0 1 1 1
 1 6 1 0 0 1 0 1
 6 6 1 0 0 0 1 1
 1 1 1 1 0 0 0 1
 1 1 1 1 1 1 1 1

實現代碼


#include <stdio.h>
#define N 19 //整個迷宮大小(包括最外層牆壁)

char Maze[N][N] = {
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    {1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0},
    {1,1,1,0,1,1,1,0,1,0,1,1,1,1,1,0,1,1,1},
    {1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1},
    {1,1,1,0,1,0,1,0,1,1,1,1,1,0,1,1,1,1,1},
    {1,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0,1},
    {1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1},
    {1,0,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1},
    {1,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,1},
    {1,0,1,0,1,1,1,0,0,0,1,0,1,0,1,0,1,0,1},
    {1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,1},
    {1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1},
    {1,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,1},
    {1,0,1,0,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1},
    {1,0,1,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,1},
    {1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1},
    {0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
char step[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};   //定義四個方向
int count = 0;

char Check(char i, char j)  //判斷下一步是不是通路
{
    if(i >= 0 && i<=18 && j >= 0 && j <= 18)
    {
        if(0 == Maze[i][j])
        {
            return 1;
        }
    }
    return 0;
}

void Display(void)
{
    char i, j;

    for(i=0; i<N; ++i)
    {
        for(j=0; j<N; ++j)
        {
            printf("%d", Maze[i][j]);
        }
        printf("\n");
    }
}

void Find(char ci, char cj)
{
    char n;
    if((N-1) == cj) //這個邊界設置得比較粗糙,到N-1這個下標就算終點,沒想到什麼好的辦法
    {
        Maze[ci][cj] = 6;   //終點的最後一個6
        printf("解法%d(Enter回車查看下一解法):\n", ++count);
        Display();
        getchar();
        Maze[ci][cj] = 0;
    }
    else
    {
        for(n=0; n<4; ++n)
        {
            if(Check(ci+step[n][0], cj+step[n][1])) //依然用Check實現判斷:是否可以在某個方向走下一步
            {
                Maze[ci][cj] = 6;   //6表示走過的路
                Find(ci+step[n][0], cj+step[n][1]);
                Maze[ci][cj] = 0;   //傳統回溯方法
            }
        }
    }
}

int main(void)
{
    printf("\t迷宮問題(1 牆壁 0 道路 6 解法)\n\n");
    printf("原迷宮(Enter回車查看解法):\n");
    Display();
    getchar();

    //(17, 0)爲起點
    Find(17, 0);

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章