搜索算法

DFS

深度优先搜索(dfs)是用来遍历或搜索树和图数据结构的算法,它是可以从任意跟节点开始,选择一条路径走到底,并通过回溯来访问所有节点的算法。
它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底。
1111

全排列问题

题目来源:洛谷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

所谓广度优先搜索,就是从图中的某个顶点出发,寻找紧邻的、尚未访问的顶点,找到多少就访问多少,然后分别从找到的这些顶点出发,继续寻找紧邻的、尚未访问的顶点。当从某个顶点出发,所有和它连通的顶点都访问完之后,广度优先搜索算法会重新选择一个尚未访问的顶点(非连通图中就存在这样的顶点),继续以同样的思路寻找未访问的其它顶点。直到图中所有顶点都被访问,广度优先搜索算法才会结束执行。
33

奇怪的电梯

题目来源:洛谷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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值