DFS
深度优先搜索(dfs)是用来遍历或搜索树和图数据结构的算法,它是可以从任意跟节点开始,选择一条路径走到底,并通过回溯来访问所有节点的算法。
它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底。
全排列问题
题目来源:洛谷P1706
题目描述
按照字典序输出自然数 1 到 n 所有不重复的排列,即 n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。
代码:
#include<bits/stdc++.h>
using namespace std;
int n;
int arr[10001];
bool brr[10001];
void dfs(int x){
if(x>n){
for(int i=1;i<=n;i++){//通过for循环一次输出n个数
cout<<" ";
cout<<arr[i];
}
cout<<endl;
}else{//要输出1-n的全排列 如果保证不重复的情况下,那你还需要一个数组来标记它是否重复出现过。
for(int i=1;i<=n;i++){
if(brr[i]==1){
continue;
}//一个 for循环。先判断它是否被使用过,也就是判断b[i]是否==1。如果是的话就说明被使用过,就直接continue
brr[i]=1;
arr[x]=i;
dfs(x+1);
brr[i]=0;//深搜完之后说明,在这一次操作里数已经排完了,要开始重新挑三个数了。那这时候你就要把原本标记的1改成0。
}
}
}
int main(){
cin>>n;
dfs(1);//输入至少大于等于1
return 0;
}
迷宫
题目来源:洛谷P1605
题目描述:给定一个 N×M 方格的迷宫,迷宫里有 T 处障碍,障碍处不可通过。在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。给定起点坐标和终点坐标,每个方格最多经过一次,问有多少种从起点坐标到终点坐标的方案。
代码:
#include<iostream>
using namespace std;
int n,m,t,sx,sy,fx,fy;
const int N=10;//N不能小于6
int arr[N][N];//这里 走过的路和障碍 存0,全局变量默认都为0
int sum=0;
void dfs(int x,int y){
if(x==fx&&y==fy){
sum++;
return;
}
else{
arr[x][y]=0;//将当前路设为走过(下次探索的路也会在此设为走过)
//四个方向探索 并回溯
if(arr[x][y-1]){dfs(x,y-1);arr[x][y-1]=1;}
if(arr[x][y+1]){dfs(x,y+1);arr[x][y+1]=1;}
if(arr[x+1][y]){dfs(x+1,y);arr[x+1][y]=1;}
if(arr[x-1][y]){dfs(x-1,y);arr[x-1][y]=1;}
}
}
int main(){
int x,y,i,j;
cin>>n>>m>>t;
cin>>sx>>sy>>fx>>fy;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
arr[i][j]=1;//先把迷宫范围内都设为可走,否则就没边界了
for(i=1;i<=t;i++){
cin>>x>>y;
arr[x][y]=0;//标出不可走的障碍
}
dfs(sx,sy);
cout<<sum;
return 0;
}
BFS
所谓广度优先搜索,就是从图中的某个顶点出发,寻找紧邻的、尚未访问的顶点,找到多少就访问多少,然后分别从找到的这些顶点出发,继续寻找紧邻的、尚未访问的顶点。当从某个顶点出发,所有和它连通的顶点都访问完之后,广度优先搜索算法会重新选择一个尚未访问的顶点(非连通图中就存在这样的顶点),继续以同样的思路寻找未访问的其它顶点。直到图中所有顶点都被访问,广度优先搜索算法才会结束执行。
奇怪的电梯
题目来源:洛谷P1135
题目描述:呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第 i 层楼(1≤i≤N)上有一个数字 K i(0<=Ki<=N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:
3,3,1,2,5 代表了 K i(K1=3,K2=3…),从 1 楼开始。在 1 楼,按“上”可以到 4 楼,按“下”是不起作用的,因为没有 −2 楼。那么,从 A 楼到 B 楼至少要按几次按钮呢?
代码:
#include <bits/stdc++.h>
using namespace std;
int a[1000],b[1000];
struct data{
int s;
int v;
}t,x;
queue<data>q;
int main()
{
int N, A, B;
cin>>N>>A>>B;
for(int i=1; i<=N; i++)
scanf("%d", &a[i]);
memset(b, 0, sizeof(b));
t.s=A;
t.v=0;
q.push(t);
b[A]=1;
while(!q.empty())
{
t=q.front();
if(t.s==B)
break;
q.pop();
if(t.s+a[t.s]>0 && !b[t.s+a[t.s]])
{
x.s=t.s+a[t.s];
x.v=t.v+1;
q.push(x);
b[x.s]=1;
}
if(t.s-a[t.s]>=0 && !b[t.s-a[t.s]])
{
x.s=t.s-a[t.s];
x.v=t.v+1;
q.push(x);
b[x.s]=1;
}
}
if(t.s==B)
cout<<t.v;
else
cout<<-1;
return 0;
}