1. 程式人生 > >迷宮問題(深搜+回溯)

迷宮問題(深搜+回溯)

    Time Limit: 1 Sec  Memory Limit:128 MB  64bit IO Format: %lld
                                 [Submit][Status][Web Board]

設有一個N*N(2<=N<10)方格的迷宮,入口和出口分別在左上角和右上角。迷宮格子中分別放0和1,0表示可通,1表示不能,入口和出口處肯定是0。迷宮走的規則如下所示:即從某點開始,有八個方向可走,前進方格中數字為0時表示可通過,為1時表示不可通過,要另找路徑。找出所有從入口(左上角)到出口(右上角)的路徑(不能重複),輸出路徑總數,如果無法到達,則輸出0。

Input

第一行一個正整數N;

接下來的包含N行,每行N個數。用來描述迷宮。

Output

輸出路徑總數。

Sample Input

3
0 0 0
0 1 1
1 0 0

Sample Output

2

  這類問題重點在於訪問過的點又可能還要再次訪問,所以用dfs加簡單回溯就可以了。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=15,sx[8]={-1,-1,-1,0,0,1,1,1}
              ,sy[8]={-1,0,1,-1,1,-1,0,1};//八個方向標記做好
int n,sum=0;
int s[N][N],
a[N][N];//是否訪問過標記
void  dfs(int x,int y)
{
    if(x==0&&y==n-1)
    {
        sum++;
        return ;
    }
    for(int i=0;i<8;i++)//依次訪問該點周圍八個方向
    {
        int nx=x+sx[i];
        int ny=y+sy[i];
        if(nx>=0&&nx<n&&ny>=0&&ny<n&&s[nx][ny]==0&&a[nx][ny]==0)//前四個為判斷是否在迷宮中  最後一個是判斷該點是否被訪問過
        {
            a[nx][ny]=1;
            dfs(nx,ny);//是沒訪問過的點並且是可行點,就繼續搜尋
            a[nx][ny]=0;//回溯,重新置為0,方便下次訪問
        }
    }
    return ;
}

int main()
{
    while(cin>>n)
    {
        sum=0;
        memset(s,0,sizeof(s));
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                cin>>s[i][j];
        a[0][0]=1;//左上角訪問過,置為1;
        dfs(0,0);
        printf("%d\n",sum);
    }
    return 0;
}
       已AC。