Backtracking
来源:互联网 发布:人人商城v2 数据库 编辑:程序博客网 时间:2024/05/24 05:31
1. Introduction
Backtracking is a method of exhaustive search. When a node reaches certain termination condition that means this path will not have solutions, the program will go back to the previous node and try another path.
2. Example
1. Generate all the strings of n bits.
int A[4];int C=0;void Print(int a[],int n){ for(int i=0;i<n;i++){ cout<<a[i]; } cout<<endl; C++;}void Binary(int n){ if(n<1){ Print(A,4); } else{ A[n-1]=0; Binary(n-1); A[n-1]=1; Binary(n-1); }}
*Here is an example when n=4.
2. Generate all the strings of length n chosen from 0,1,,,,k-1.
int A[5];int C=0;void Print(int a[],int n){ for(int i=0;i<n;i++){ cout<<a[i]; } cout<<endl; C++;}void kstring(int n,int k){ if(n<1){ Print(A,5); } else{ for(int i=0;i<k;i++){ A[n-1]=i; kstring(n-1,k); } }}
*Here is an example when n=5.
3. Combination
int A[5]={1,2,3,4,5};int R[3];int C=0;void Print(int a[],int n){ for(int i=0;i<n;i++){ cout<<a[i]; } cout<<endl; C++;}void Combination(int start,int n,int a[],int r[]){ if(n<1){ Print(r,3); } else{ for(int i=start;i<=5-n;i++){ r[3-n]=a[i]; Combination(i+1,n-1,a,r); } }}
*Here is an example of choose 3 from 5.
4. Full permutation
Method1:
void Swap(int* a,int* b){ int t=*a; *a=*b; *b=t;}void Permutation(int t[],int n,int start,int end){ if(n<1){ Print(t,3); } else{ for(int i=start;i<=end;i++){ Swap(&t[start],&t[i]); Permutation(t,n-1, start+1, end); Swap(&t[start],&t[i]); } }}
*Here is an example of a list with 3 elements.
Method2:
const int n=5;int numbers[5]={1,2,3,4,5};int R[5];int indicate[5]={0};int C=0;void Print(int A[],int m){ for(int i=0;i<m;i++){ cout<<A[i]<<' '; } cout<<endl; C++;}void Permutation(int cur){ if(cur>=n) Print(R, n); else{ for(int i=0;i<n;i++){ if(!indicate[i]){ R[cur]=numbers[i]; indicate[i]=1; Permutation(cur+1); indicate[i]=0; } } }}
Note that here it is necessary to have a R list to store the current solution. If we use the list numbers to store solutions, the problem is that the index of numbers will change and hence the indicate list will record the wrong situation.
5. Permutation
void Print(int a[],int n){ for(int i=0;i<n;i++){ cout<<a[i]; } cout<<endl; C++;}void Swap(int* a,int* b){ int t=*a; *a=*b; *b=t;}void Permutation(int t[],int n,int start,int end){ if(n<1){ Print(t,3); } else{ for(int i=start;i<=end;i++){ Swap(&t[start],&t[i]); Permutation(t,n-1, start+1, end); Swap(&t[start],&t[i]); } }}void Combination(int n,int start, int a[],int r[]){ if(n<1){ Permutation(r,3, 0, 2); } else{ for(int i=start;i<=5-n;i++){ r[3-n]=a[i]; Combination(n-1, i+1, a, r); } }}
*Here is an example of choose 3 from 5, the basic idea is to find all combinations first and then do full permutation to each combination.
3. Problems and solutions
1. N-Queen problem
void search(int curline){ if(curline==n) { tot++; for(int i=0;i<n;i++){ cout<<C[i]<<' '; } cout<<endl; } else{ for(int i=0;i<n;i++){ int ok=1; C[curline]=i; for(int j=0;j<curline;j++){ if(C[curline]==C[j]||curline-C[curline]==j-C[j]||curline+C[curline]==j+C[j]){ ok=0; break; } } if(ok) search(curline+1); } } }
Here we use a one-dimension list to indicate the position of chess and we use mathematical relation between line and column number as if-conditions to determine whether the solution is acceptable.
We can also do this in the following method:
void search(int cur){ if(cur==n){ tot++; for(int i=0;i<n;i++){ cout<<C[i]<<' '; } cout<<endl; } else{ for(int i=0;i<n;i++){ if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][i-cur+n]){ C[cur]=i; vis[0][i]=vis[1][cur+i]=vis[2][i-cur+n]=1; search(cur+1); vis[0][i]=vis[1][cur+i]=vis[2][i-cur+n]=0; } } }}
Here we use a two-dimensional list vis to indicate the column and diagonals that are already occupied by previous chess. Note that after recursively call function search for the next line, we need to change back the value of that position in vis for it to work on the next column of the current line.
2. Prime Ring Problem (UVa 524)
Method 1: (Enumeration, brute force)
#include <iostream>#include <cmath>using namespace std;int const n=6;int inputs[n]={1};int isp[2*n+1];int is_prime(int a){ int t=sqrt(a); int ok=1; for(int i=2;i<=t;i++){ if(a%i==0){ ok=0; break; } } if(ok) return 1; else return 0;}void Swap(int*a, int*b){ int t=*a; *a=*b; *b=t;}void Print(int A[],int m){ for(int i=0;i<m;i++){ cout<<A[i]<<' '; } cout<<endl;}void Decide(){ int ok=1; for(int i=0;i<n;i++){ if(!isp[inputs[i]+inputs[(i+1)%n]]){ ok=0; break; } } if(ok) Print(inputs,n);}void Permutation(int start){ if(start>=n){ Decide(); } else{ for(int i=start;i<n;i++){ Swap(&inputs[i],&inputs[start]); Permutation(start+1); Swap(&inputs[i],&inputs[start]); } }}int main(){ for(int i=0;i<n;i++){ inputs[i]=i+1; } for(int i=2;i<=2*n;i++){ isp[i]=is_prime(i); } Permutation(1);}
This method will exceed time limit when n gets bigger.
Method 2: (Backtracking)
#include <iostream>#include <cmath>using namespace std;const int n=6;int A[n]={1};int vis[n]={0};int is_prime(int a){ int t=sqrt(a); int ok=1; for(int i=2;i<=t;i++){ if(a%i==0){ ok=0; break; } } if(ok) return 1; else return 0;}void Print(int A[],int m){ for(int i=0;i<m;i++){ cout<<A[i]<<' '; } cout<<endl;}void dfs(int cur){ if(cur==n&&is_prime(A[0]+A[n-1])){ Print(A, n); } else{ for(int i=2;i<=n;i++){ if(!vis[i]&&(is_prime(i+A[cur-1]))){ A[cur]=i; vis[i]=1; dfs(cur+1); vis[i]=0; } } }}int main(){ dfs(1);}
3. Krypton Factor (UVa 129)
#include <iostream>#include <cstdio>using namespace std;const int L=3;const int n=30;int S[200];int cnt=0;int dfs(int cur){ if(cnt==n){ for(int i=0;i<cur;i++){ printf("%c",'A'+S[i]); } printf("\n"); return 0; } for(int i=0;i<L;i++){ S[cur]=i; int ok=1; for(int j=1;j<=(cur+1)/2;j++){ int equal=1; for(int k=0;k<j;k++){ if(S[cur-k]!=S[cur-k-j]){ equal=0; break; } } if(equal){ ok=0; break; } } if(ok){ cnt++; if(!dfs(cur+1)){ return 0; } } } return 1;}int main(){ dfs(0);}
- backtracking
- BackTracking
- Backtracking
- Backtracking
- Backtracking
- Backtracking
- [leetcode] backtracking
- DFS + BackTracking
- Backtracking Algorithm
- Backtracking questions
- BackTracking回溯
- The backtracking algorithm
- 639 Backtracking Easy
- 【索引】Backtracking - Easy
- 【索引】Backtracking - Hard
- 【转载】leetcode中的backtracking
- LeetCode 回溯算法 backtracking
- 【索引】Backtracking - Easy
- D3绘制柱状图
- mysql命令行常用命令
- 【Android】系统相机、相册获取照片并显示
- html和xml
- 一款非常漂亮的bootstrap表单checkbox/radio样式推荐
- Backtracking
- 排序
- swift中的for循环
- RxJava使用笔记
- RecyclerView子View不刷新(RequestLayout无效),RecyclerView.mEatRequestLayout
- Oracle监听的常用命令及监听日志分析
- 由一个私有静态变量的处理问题谈java内存模型
- API文档自动生成工具
- 461. Hamming Distance