zoukankan      html  css  js  c++  java
  • 搜索与回溯

    首先,搜索就是从上一层进一步探索下一层。

    就是与闯关游戏差不多,由上一层进入下一层,依照所拥有的信息,进行深入探索。

    所以搜索就是向下走一步,倘若得到解就输出。

    当然,这里还有回溯,搜索到了底端,就无路可走,自然就要回退一步甚至是多步。

    这就是搜索回溯算法。

    搜索回溯算法有两种模式:

    第一种:

    int Search(int k)
     {
     for (i=1;i<=算符种数;i++)
      if (满足条件)
         {
        保存结果
        if (到目的地) 输出解;
                  else Search(k+1);
        恢复:保存结果之前的状态{回溯一步}
         }
     }

    第二种:

    int Search(int k)
     {
       if  (到目的地) 输出解;
       else
        for (i=1;i<=算符种数;i++)
         if  (满足条件) 
           {
            保存结果;
                         Search(k+1);
            恢复:保存结果之前的状态{回溯一步}
           }
     }

    这里给出一道例题:

    经典例题啊:

    八皇后

    这道题略微有所改变,就是它只需要输出前四个解。

    当然,我仍然会将八个皇后的题解放上来。

    //放置第i个(行)皇后的算法为:
    int search(i);
     {
         int j;
       for (第i个皇后的位置j=1;j<=8;j++ )        //在本行的8列中去试
       if (本行本列允许放置皇后)
        {
         //放置第i个皇后;
                     // 对放置皇后的位置进行标记;
         if (i==8) 输出                                  //已经放完个皇后
            else search(i+1);                //放置第i+1个皇后
         //对放置皇后的位置释放标记,尝试下一个位置是否可行;
        }
     }

    这是算法的基本思路

    这题运用的方法是深度优先搜索

    #include<bits/stdc++.h>
    using namespace std;
    int a[100],k,n,ans=0;
    int check(int k,int c)//选择
    {
         for(int i = 1;i<k;i++){
            if(a[i] == c||abs(a[i]-c)==abs(k-i)) return 0;
             }
        return 1;
    }
    void dfs(int k)//深搜函数,其实和搜索回溯没什么两样
    {
        if(k>n)
        if(ans>=3) ans++;
        else
        {
            ans++;
            for(int i=1;i<=n;i++)
            cout<<a[i]<<" ";
            cout<<endl;
        }
        else
        {
          for(int i=1;i<=n;i++)
         {
          if(check(k,i))
            {
                a[k]=i;
                dfs(k+1);
                a[k]=0;
            }
         }
        }
    }
    int main()
    {
        cin>>n;
        dfs(1);
        printf("%d",ans);
        return 0;
    }

    当然,原题下面的题解只是测试

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<iomanip>
    using namespace std;
    bool d[100]={0},b[100]={0},c[100]={0};
    int sum=0,a[100];
    int search(int);
    int print();
    int main()
    {
       search(1);
    }
    int search(int i)
    {
      int j;
      for (j=1;j<=8;j++) //每个皇后都有8位置(列)可以试放
      if ((!b[j])&&(!c[i+j])&&(!d[i-j+7])) //寻找放置皇后的位置,由于C++不能操作负数组,因此考虑加7 
          {
          a[i]=j; //放置皇后,建立相应标志值
          b[j]=1;  //摆放皇后
          c[i+j]=1; //宣布占领第j列
          d[i-j+7]=1;//占领两个对角线
          if (i==8) print();//8个皇后都放置好,输出
            else search(i+1);   //继续递归放置下一个皇后
          b[j]=0;//递归返回即为回溯一步,当前皇后退出
          c[i+j]=0;
          d[i-j+7]=0;
          }
    }
    int print()
    {
        int i;
        for (i=1;i<=8;i++)
          cout<<setw(4)<<a[i];
        cout<<endl; 
    }
  • 相关阅读:
    nginx 配置7层代理
    还用老套路分析财务数据?这3种财务分析方法,你一定得看看
    nginx 4层代理
    【手绘漫画】面试必考之手撕单链表(解题模板和深度剖析),(LeetCode 707)
    连载三:Oracle升级文档大全
    隐私保护与价值挖掘之利器
    PTA刷题笔记(C语言) | 7-42 整除光棍 (20分)
    django 页面缓存
    C++建议
    读陈浩的《C语言结构体里的成员数组和指针》总结,零长度数组
  • 原文地址:https://www.cnblogs.com/U58223-luogu/p/9528449.html
Copyright © 2011-2022 走看看