首先,搜索就是从上一层进一步探索下一层。
就是与闯关游戏差不多,由上一层进入下一层,依照所拥有的信息,进行深入探索。
所以搜索就是向下走一步,倘若得到解就输出。
当然,这里还有回溯,搜索到了底端,就无路可走,自然就要回退一步甚至是多步。
这就是搜索回溯算法。
搜索回溯算法有两种模式:
第一种:
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; }