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;
}


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