例1 素数环
【分析】
1.判断素数
2.判断合法
【代码】
#include <bits/stdc++.h>
using namespace std;
int a[25],b[25];
int n;
int pd(int n){
int flag=1;
for(int i=2;i<=n/i;i++){
if(n%i==0){
flag=0;
break;
}
}//素数判断
return flag;
}
void dfs(int m){
if(m==n+1){
if(pd(a[n]+a[1])){
for(int i=1;i<=n;i++){
cout<<a[i]<<" ";
}
cout<<endl;
}
}
else{
for(int i=2;i<=n;i++){
if(b[i]==0 && pd(i+a[m-1])){
a[m]=i;
b[i]=1;//把i标记掉
dfs(m+1);
b[i]=0;//消除标记
}//判断是否合法
}
}
}
int main(){
cin>>n;
a[1]=1;
b[1]=1;
dfs(2);//从第二个开始搜索
}
【分析】
1.输出格式
2.标记与清除
【代码】
#include <bits/stdc++.h>
#include <cstring>
using namespace std;
/*string s[105],a;
int main(){
scanf("%s",s);
int n=0;
s[++n]=a;
for(int i=1;i<n;i++){
for(int j=1;j<=n-1;j++){
if(s[j]>s[j+1]) swap(s[j],s[j+1]);
n=unique(s+1,s+1+n)-(s+1);
}
}
for(int i=1;i<=n;i++) cout<<s[i]<<endl;
return 0;
}*/
int a[10],b[10];
int n;
void dfs(int m){
if(m==n+1){
for(int i=1;i<=n;i++){
printf("%5d",a[i]);
}
cout<<endl;
}
else{
for(int i=1;i<=n;i++){
if(b[i]==0){
a[m]=i;
b[i]=1;
dfs(m+1);
b[i]=0;
}
}
}
}
int main(){
cin>>n;
dfs(1);
}
【分析】
1.n-1种选择
【代码】
#include <bits/stdc++.h>
using namespace std;
int a[10],n;
int dfs(int m,int s){
if(s==0){
cout<<a[1];
for(int i=2;i<m;i++){
cout<<'+'<<a[i];
}
cout<<endl;
}
else{
for(int i=1;i<n;i++){
if(i>=a[m-1]&&(i<=s-i||i-s==0)){
a[m]=i;
dfs(m+1,s-i);
}
}
}
}
int main(){
cin>>n;
dfs(1,n);
}
【分析】
1.矩阵寻找规律
2.标记不安全的位置
3.一维与二维
【代码1】
【代码2】
#include <bits/stdc++.h>
using namespace std;
int a[20],b[20],zx[20],yx[20];
int ans=0;
void dfs(int i){
if(i==9){
ans++;
printf("No. %d\n",ans);
for(int i=1;i<=8;i++){
for(int j=1;j<=8;j++){
if(a[j]==i) cout<<1<<" ";
else cout<<0<<" ";
}
cout<<endl;
}
}
else{
for(int j=1;j<=8;j++){
if(b[j]==0 && zx[i+j]==0 && yx[i+8-j]==0){
a[i]=j;
b[j]=1;
zx[i+j]=1;
yx[i+8-j]=1;
dfs(i+1);
b[j]=0;
zx[i+j]=0;
yx[i+8-j]=0;
}
}
}
}
int main(){
dfs(1);
}
例5 马的遍历
【分析】
1.偏置数组
2.考虑边界
3.起始位置
4.输出格式
【代码】
#include <bits/stdc++.h>
using namespace std;
int xx[4]={2,1,-1,-2};
int yy[4]={1,2,2,1};
int a[20],b[20];
int n,m;
void dfs(int x,int y,int l){
if(x==n && y==m){
printf("0,0");
for(int i=2;i<l;i++){
printf("->%d,%d",a[i],b[i]);
}
cout<<endl;
}
else{
int kx,ky;
for(int i=0;i<4;i++){
kx=x+xx[i];
ky=y+yy[i];
if(kx>n || kx<0 || ky>m || ky<0) continue;
a[l]=kx;
b[l]=ky;
dfs(kx,ky,l+1);
}
}
}
int main(){
cin>>n>>m;
a[0]=b[0]=0;
dfs(0,0,1);
}
Practice
本文介绍了五道经典的回溯算法题目,包括素数环、全排列、自然数拆分、八皇后问题及马的遍历。每道题目都详细分析了解题思路,并提供了完整的C++代码实现。





