1.搜索与回溯算法的思想
搜索与回溯是计算机解题中常用的算法,很多问题无法根据某种确定的计算法则来求解,可以利用搜索与回溯的技术求解。
回溯是搜索算法中的一种控制策略。
它的基本思想是:为了求得问题的解,先选择某一种可能情况向前探索,在探索过程中,一旦发现原来的选择是错误的,就退回一步重新选择,继续向前探索,如此反复进行,直至得到解或证明无解。
如迷宫问题:进入迷宫后,先随意选择一个前进方向,一步步向前试探前进,如果碰到死胡同,说明前进方向已无路可走,这时,首先看其它方向是否还有路可走,如果有路可走,则沿该方向再向前试探;如果已无路可走,则返回一步,再看其它方向是否还有路可走;如果有路可走,则沿该方向再向前试探。按此原则不断搜索回溯再搜索,直到找到新的出路或从原路返回入口处无解为止。
2.递归回溯法算法模板
模板1
int search(int k)
{
if(达到目的)
{
输出解;
}
for(int i=1;i<=算符种数;i++)
{
if(满足条件)
{
保存结果;
search(k+1);
恢复:保存结果之前的状态{回溯一步}
}
}
}
模板2
int search(int k)
{
for(int i=1;i<=算符种数;i++)
{
if(满足条件)
{
保存结果;
if(到目的地)
{
输出解;
}
else
{
search(k+1);
}
恢复:保存结果之前的状态{回溯一步}
}
}
}
例题
素数环
题目描述
输入正整数n,把整数1,2,3,…,n 组成一个环,使得相邻两个整数之和为素数。输出时从整数1 开始按字典序逆时针排列,同一个环恰好输出一次。
输入格式
输入一个整数:n。
输出格式
输出若干行,每行一个排列,从整数1 开始按字典序顺时针排列。
输入样例
16
输出样例
11 4 3 2 5 61 6 5 2 3 4
代码
#include<bits/stdc++.h>
using namespace std;
const int N=30;
int n,a[N],cnt=0;
bool vis[N];
bool isprime(int x)
{
if(x<2)
return false;
int m=(int)sqrt(x+0.5);
for(int i=2;i<=m;i++)
if(x%i==0)
return false;
return true;
}
void print()
{
cnt++;
cout<<cnt<<": ";
for(int i=1;i<=n;i++)
if(i!=n)
printf("%d ",a[i]);
else
printf("%d\n",a[i]);
}
void dfs(int k)
{
if(k==n+1)
{
if(isprime(a[n]+a[1]))
print();return;
}
for(int i=2;i<=n;i++)
if(vis[i]==0&&isprime(a[k-1]+i))
{
a[k]=i;vis[i]=1;
dfs(k+1);vis[i]=0;a[k]=0;
}
}
int main()
{
cin>>n;
a[1]=1;
vis[1]=1;
dfs(2);
return 0;
}