广度优先搜索(蓝桥杯)

 入队

通过push()方法在队尾插入一个新的元素。

#include <queue>
using namespace std;
int main(){
    queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    return 0;
}
获取队首元素

通过front()方法可以获取到当前的队首元素。

#include <queue>
#include <iostream>
using namespace std;
int main(){
    queue<int> q;
    q.push(1);
    cout<<q.front()<<endl;
    q.push(2);
    cout<<q.front()<<endl;
    q.push(3);
    cout<<q.front()<<endl;
    return 0;
}
出队

通过pop()方法可以让队首元素出队。

#include <queue>
#include <iostream>
using namespace std;
int main(){
    queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    q.pop();
    cout<<q.front()<<endl;
    q.pop();
    cout<<q.front()<<endl;
    q.pop();
    return 0;
}
判断队列是否为空

empty()方法可以判读队列是否为空,如果为空,方法返回true,否则返回false。这个方法的意义是,在我们每次调用front()pop()之前,都要检查一下,保证队列不为空,否则去访问一个空队列的首部或者让一个空队列出队就会发生错误。

#include <queue>
#include <iostream>
using namespace std;
int main(){
    queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    while(!q.empty()){//如果队列不空,一直出队,用这样的方法清空一个队列,因为队列没有clear方法
        cout<<q.front()<<endl;
        q.pop();
    }
    return 0;
}
清空

队列比较特殊,并没有clear()方法,而清空一个队列,需要手动清空。

while(!q.empty()){//如果队列不空,一直出队,用这样的方法清空一个队列,因为队列没有clear方法
        cout<<q.front()<<endl;
        q.pop();
    }
#include <queue>
#include <iostream>
#include <string>
using namespace std;
int main(){
    queue<string> q;
    q.push("zhangsan");
    q.push("lisi");
    q.push("wangwu");
    while(!q.empty()){
        cout<<q.front()<<endl;
        q.pop();
    }
    return 0;
}

演算发现结果是6,

#include <queue>
#include <iostream>

using namespace std;

int main(){
    int n,m;
    cin>>n>>m;
    queue<int> q;
    for(int i=1;i<=n;i++){
        q.push(i);
    }
    int cur=1;
    while(q.size()>1){
        int x=q.front();
        q.pop();
        if(cur==m){
            cur=1;
        }else{
            q.push(x);
            cur++;
        }
    }
    cout<<q.front()<<endl;
    return 0;
}
广度优先搜索

void  bfs(起始点){
         将起始点放入队列中;
         标记起始点访问;
         while(如果队列不为空){
            访问队列中队首元素x;
            删除队首元素;
            for(x所有相邻点){
                if(该点未被访问过且合法){
                    将该点加入队列末尾;
                }
            }
         }
         队列为空,广搜结束;
}

 

#include <iostream>
#include <string>
#include <queue>

using namespace std;

int n,m;
string maze[110];
bool vis[110][110];
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};

bool in(int x,int y){
    return 0<=x && x<=n && 0<=y && y<=m;
}

struct node{
    int x,y,d;
    node(int xx,int yy,int dd){
        x=xx;
        y=yy;
        d=dd;
    }/*在结构体中定义一个构造函数,当创建一个 node 类型的对象时,可以通过传入参数来调用构造函数,从而初始化对象的 x, y, d 成员变量。*/
};

int bfs(int sx,int sy){
    queue<node> q;
    q.push(node(sx,sy,0));
    vis[sx][sy]=true;
    while(!q.empty()){
        node now =q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int tx=now.x+dir[i][0];
            int ty=now.y+dir[i][1];
            if(in(tx,ty)&&maze[tx][ty]!='*'&&!vis[tx][ty]){
                if(maze[tx][ty]=='T'){
                    return now.d+1;
                }else{
                    vis[tx][ty]=true;/*虽然在判断条件中有 !vis[tx][ty] 这个条件,但在实际处理中,可能会存在多个路径经过相同的位置,所以需要确保每个位置只被访问一次,避免重复访问或者形成死循环。因此,即使在 if 语句块中已经判断了 !vis[tx][ty],为了确保正确性和完整性,还是会在访问该位置后将其标记为已访问 vis[tx][ty] = true;。这样可以避免程序出现错误或进入死循环,确保算法能够正确地搜索到最短路径。*/
                    q.push(node(tx,ty,now.d+1));
                }
            }
        }
    }
    return -1;//没有找到路径
}

int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++){
        cin>>maze[i];
    }
    int x,y;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(maze[i][j]=='S'){
                x=i,y=j;
            }
        }
    }
    cout<<bfs(x,y)<<endl;
    return 0;
}

#include <iostream>
#include <queue>
#include <cstdio>

using namespace std;

queue<pair<int,int> > q;  // 定义一个队列用于存储待访问的节点坐标以及步数
bool vis[5005];  // 定义一个数组用于标记节点是否被访问过

int main(){
    int n, A, B, now, step;
    scanf("%d%d%d", &n, &A, &B);  // 输入总长度 n,起点 A,终点 B
    q.push(make_pair(A, 0));  // 将起点 A 和步数 0 入队
    vis[A] = true;  // 标记起点 A 已被访问

    while(!q.empty()){
        now = q.front().first;  // 获取当前节点
        step = q.front().second;  // 获取到达当前节点的步数
        q.pop();  // 出队当前节点

        if(now == B){  // 如果当前节点为终点 B,输出步数并结束循环
            printf("%d\n", step);
            break;
        }

        // 分别尝试向前、向后、向倍增的方向移动一步,并将新节点入队
        if(now + 1 <= n && !vis[now + 1]){
            q.push(make_pair(now + 1, step + 1));
            vis[now + 1] = true;
        }
        if(now - 1 >= 0 && !vis[now - 1]){
            q.push(make_pair(now - 1, step + 1));
            vis[now - 1] = true;
        }
        if(now * 2 <= n && !vis[now * 2]){
            q.push(make_pair(now * 2, step + 1));
            vis[now * 2] = true;
        }
    }

    return 0;
}

pair 是 C++ STL(标准模板库)中的一个模板类,用于表示一对值。它可以存储两个值,这两个值的类型可以不同。例如,pair<int, string> 可以存储一个整数和一个字符串。make_pair 是一个函数模板,用于创建一个 pair 对象并初始化其值。

在使用 pair 时,可以使用 firstsecond 成员变量来访问其中的第一个值和第二个值。例如:

pair<int, string> p = make_pair(10, "hello");
cout << p.first << " " << p.second << endl;  // 输出:10 hello
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LONG_shuishui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值