一、深度优先搜索
1.理解 深度优先搜索,是一种自上而下的搜索方式,蕴含着递归的思想,在模板题中,需要注意的是:
1.注意递归的结束标志,从第0位开始搜索,在位数u==n时代表着结束,而不是u==n-1时结束。
2.在搜索完一位后,递归搜索下一位时,要对数组进行还原,还原到以前的样子,在排列中即为book[i]要重新定义为false,代表没有用过该数字。
3.含义:
book[i]: 标记使用过的数
a[i]:存储排序结果
模板如下:
#include <iostream>
using namespace std;
const int N=10;
int a[N];
int book[N];
int n;
void dfs(int u){
if(u==n){
for(int i=0;i<n;i++) cout <<a[i]<<" ";
cout <<endl;
}
else {
for(int i=1;i<=n;i++){
if(!book[i]){
a[u]=i;
book[i]=true;
dfs(u+1);
book[i]=false;//重新标记为false,代表没有用过,进行下一次循环
}
}
}
}
int main(){
cin>>n;
dfs(0);
}
2.n-皇后问题
思路和上题类似,同样是利用dfs,在这里是对它的每一行的列进行搜索,判断每一列、每一行、以及对角线上是否有重复元素。
含义:
a[N][N]:代表棋盘
rol[N] d[N] ud[N]:分别用来标记列、对角线、反对角线上是否有元素出现
#include <iostream>
#include <cstring>
using namespace std;
const int N=12;
int n;
char a[N][N];//作为棋盘进行标记
bool rol[N],d[N],ud[N];
void dfs(int u){
if(u>=n) {
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) cout <<a[i][j];
cout <<endl;
}
cout <<endl;
return;
}
else {
for(int i=1;i<=n;i++){//u代表行,i代表列
if(!rol[i]&&!d[n-i+u]&&!d[i+u]){
a[u][i]='Q';
rol[i]=d[n+i-u]=d[i+u]=true;
dfs(u+1);
rol[i]=d[n+i-u]=d[i+u]=false;
a[u][i]='.';
}
}
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=0;j<n;j++){
a[i][j]='.';
}
}
dfs(1);
}
3.栈
是一种比较好理解的数据结构,遵循 ”先进后出“ 的原则,仅需要一个数组以及指向栈顶的指针tt即可实现。栈可以用数组模拟,同时也有其专门的头文件和实现一系列操作的函数。
用数组模拟的代码如下:
#include <iostream>
#include <string>
using namespace std;
const int N=1e5+10;
int stk[N],tt;
int main(){
int n;
cin>>n;
while(n--){
string ch;
cin>>ch;
if(ch=="push"){
int x;
cin>>x;
stk[++tt]=x;
}
else if(ch=="pop"){
tt--;
}
else if(ch=="empty"){
if(tt==0) cout <<"YES"<<endl;
else cout <<"NO"<<endl;
}
else {
cout <<stk[tt]<<endl;
}
}
}