暑假訓練第7天,今天學的深度搜索DFS和廣度搜索BFS

在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請編程求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案C。

Input

輸入含有多組測試數據。 
每組數據的第一行是兩個正整數,n k,用一個空格隔開,表示了將在一個n*n的矩陣內描述棋盤,以及擺放棋子的數目。 n <= 8 , k <= n 
當爲-1 -1時表示輸入結束。 
隨後的n行描述了棋盤的形狀:每行有n個字符,其中 # 表示棋盤區域, . 表示空白區域(數據保證不出現多餘的空白行或者空白列)。 

Output

對於每一組數據,給出一行輸出,輸出擺放的方案數目C (數據保證C<2^31)。

Sample Input

2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1

Sample Output

2
1
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

char a[10][10];     //記錄棋盤位置
int book[10];        //記錄一列是否已經放過棋子,放過則記爲1.沒放過記爲0 
int n,k;
int total,m;    //total 是放棋子的方案數 ,m是已放入棋盤的棋子數目

void DFS(int cur)
{
    if(k==m)//以放入的棋子數等於棋子總數 
    {
        total++;//方案+1 
        return ;
    }
    if(cur>=n)    //邊界

        return ;
    for(int j=0; j<n; j++)
        if(!book[j] && a[cur][j]=='#')  //判斷條件book[j]就是第J列爲0時然後並且cur行j列是棋盤 
        {
            book[j]=1;           //則標記一下 這一列放一個 
            m++;                 // 放的棋子數+1 
            DFS(cur+1);            //繼續判斷下一行 
            book[j]=0;           //改回來能夠下一次的判斷
            m--;                //放過的棋子-1 
        }
    DFS(cur+1);                //到下一行
}

int main()
{
    int i,j;
    while(scanf("%d%d",&n,&k)&&n!=-1&&k!=-1) //限制條件
    {
        total=0;
        m=0;
        for(i=0; i<n; i++)
        for(j=0;j<n;j++)
            cin>>a[i][j];
        memset(book,0,sizeof(book));
        DFS(0);
        printf("%d\n",total);
    }
    return 0;
}

看了一天才看懂,

我理解的DFS就是一條路走到黑,直到撞到南牆纔回頭,

然後下面我來用我自己的語言來解釋一下這道題

看圖

先輸入這個二維數組

。 #。# 

。# # #

# # 。#

# # # 。

然後#的地方是可以放棋子的,然後開始放用深度DFS搜索先確定第一行的第一個能放棋子的那一列之後標記一下這一列

然後放棋子,進行遞歸(進入下一行重複操作還是下一行從第一列判斷是否有標記,然後有沒有#是否可以放棋子),像這一題

就是第一行放的2,第二行放的3,然後第三行放的1,然後第四行沒法放,執行最後的DFS(cur+1),return返回上一層

也就是第三行,然後第三行放到第4個,然後遞歸進入第4行,放第一個,然後成功棋子數=放入棋子數方案+1,

return上一層(也就是第3層,發現第三層沒有了,),執行最後的DFS然後返回上一層(第二層),然後第二層放到4

執行DFS,第3層放到1,然後DFS第四層放到3,然後執行最後的DFS,然後成功棋子數=放入棋子數方案+1,之後返回第4層

清空,然後循環判斷沒有可以放旗子的位置,然後執行最後的DFS進入第5層,越界然後返回第四層再返回第3層,發現也沒有位置可以放,之後繼續返回到第2層然後循環到第4列之後DFS。。。。。之後return,return到第一層,然後第一層第4繼續做遍歷

直到做完停止。

 

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