coj-Checker Challenge

http://202.204.102.161/showproblem.php?problemid=1190


這是第一次解決回溯的問題,之前也看過相關的一些書,不過由於遞歸函數理解的不好,也就一直沒有信心去做回溯的問題。還好,沒有想象中的那麼難。真的是隻有實際動手才知道會不會。


題意:有些像八皇后問題,就不多介紹了。


1、做題的過程中也遇到了幾個問題,遞歸調用函數的時候開始寫的是dfs(hang+1),後來發現這樣寫是錯誤的,原因是hang的值並沒有發生變化,改成這樣就對了dfs(++hang)。


2、剛開始寫的是hang==len ,後來發現了錯誤改成了hang==len+1。這個地方要len+1,因爲hang表示剛進入當前hang,這時還沒有對當前的行進行分析討論,當討論完最後一行進入的應該是len+1行。


3、判斷當前行的點的位置時,要與之前所有行進行討論,而不僅只是前一行。這裏要用到循環語句。


此外,通過第一次做的這道回溯算法題,對dfs和遞歸調用函數還有解答樹的一些概念瞭解的更深刻了。回溯法就像是在一棵樹上搜索,當前面沒有路了,這時候往往會遇到return 語句,結束當前的調用,返回上一級,如果上一級還有路可以走,就走下去,若沒有,則在程序中還會遇到return 語句,繼續返回上一層,直到有路可走或找到結果。

以前一直對回溯的過程理解的不太好,通過做題,現在的理解就是遞歸調用函數(例如下面代碼中的dfs(hang))之後進行回溯,一般是對遞歸函數之前的一些恢復操作。比如調用函數前面是hang++,後面要執行hang--;還有就是之前不理解遞歸調用中的return語句,一些問題中return是要返回具體的數值,這是題目所要求的。而本道題的return僅僅是結束當前這一層的遞歸函數,沒有什麼實際意義。

</pre><p></p><p><span style="font-size:18px"></span></p><p><span style="font-size:18px"></span></p><pre code_snippet_id="413430" snippet_file_name="blog_20140701_2_5707023" name="code" class="cpp">#include<iostream>
using namespace std;
int len;
int a[15];
int sum=0,ans=0;
int visit[15];
bool safe(int hang,int temp)
{
    for(int i=1; i<=hang-1; i++)
    {
        if(a[i]+i==temp+hang)
            return 0;
        if(a[i]-i==temp-hang)
            return 0;
        if(a[i]==temp)
            return 0;
    }
    return 1;
}
int dfs(int hang)
{
    if(hang==len+1) //這個地方要len+1,因爲hang表示剛進入當前hang,還沒有對當前行進行討論
    {
        sum++;
        if(ans==3)
            return 0;
        cout<<a[1];
        for(int i=2; i<=len; i++)
            cout<<" "<<a[i];
        cout<<endl;
        ans++;
        return 0;
    }
    for(int i=1; i<=len; i++)
    {      
        if(hang!=1)
        {
            if(!safe(hang,i))
                continue;
        }
        a[hang]=i;
        hang++;         //  其實這三行可以簡寫爲    dfs(hang+1)   這樣也可以的,之前第一次寫DFS回溯難免拙計
        dfs(hang);      //之前寫的是hang+1,結果錯了,因爲hang這個值本身並沒有變化
        hang--;        // 
    }
    return 0;
}
int main()
{
    cin>>len;
    dfs(1);
    if(sum>=3)
        cout<<sum<<endl;
    return 0;
}


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