蓝桥杯算法入门_09 (BFS)

目录

广度优先搜索 BFS

报数游戏 (约瑟夫环)

迷宫的bfs 走一步能走到哪,走两步能到哪...

坐标移动

密码锁


广度优先搜索 BFS

一层一层的搜

运用数据结构 队列 queue 先进先出
queue<T> 队列名

front()  返回队首元素值
push()  入队尾
pop()    让队首元素出队
empty() 判断队列是否为空
没有clear
可以循环出队 直到队空 等效 clear     while( !q.empty() )  q.pop()

#include <iostream>
using namespace std;
#include<queue>
#include<string>

报数游戏 (约瑟夫环)

报到数n的人出队,输出最后剩下的人的序号


样例输入:
7 5

输出:
6


void test_01() {
    int n,m; //n为人数  , m为报到需要出队的数
    cin >> n>> m;
    queue<int > q;
    for(int i = 1; i <= n; i++) {   //编号从1开始
        q.push(i);
    }
    int cur = 1;  //当前正在报的数
    while(q.size() > 1) { //剩最后一人
        int x  = q.front(); //*** 存队头,队头不断变换 , 先出队看是不是报m 出队,不是把x == q.front()放队尾,
        q.pop();
        if(cur == m) {   //重新一轮报
            cur = 1;
        } else {
            q.push(x); //放入不出队的
            cur++;
        }
    }
    cout<< q.front();
    return;
}

迷宫的bfs 走一步能走到哪,走两步能到哪...


能搜最短路径

样例输入:
5 6
....S*
.**...
.*..*.
*..**.
.T....

输出:
7


char maze_02[100][100];
int n_02,m_02;
bool vis_02[100][100];
int dir_02[4][2] = { {-1,0},{0,-1},{1,0},{0,1} } ;
bool in_02(int x,int y) { //不越界
    return 0 <= x && x< n_02 && 0 <= y && y < m_02;
}

struct node_02 {  //用队列存放坐标,创一个结构体
    int x,y,d;
    node_02(int xx,int yy,int dd) {
        this->x = xx;
        y = yy;
        d = dd;
    }
};
int bfs_02(int sx, int sy) { //strat起始坐标 (x,y)
    queue<node_02> q; //结构体类型!!!
    q.push(node_02(sx,sy,0));//存放起始点
    vis_02[sx][sy] = true; //起点可以走
    while(!q.empty()) {
        node_02 now = q.front(); //当前坐标 进行下一步搜索 ,先出队     存结构体变量.
        q.pop();
        for(int i = 0; i < 4; i++) { //遍历搜索
            int tx = now.x + dir_02[i][0];
            int ty = now.y + dir_02[i][1];
            if(in_02(tx,ty) && maze_02[tx][ty] != '*' && !vis_02[tx][ty] ) {  //允许走的条件  不越界、无障碍 、 未标记走过
                if(maze_02[tx][ty] == 'T') {  //到终点
                    return now.d + 1;  //返回步数
                } else {
                    vis_02[tx][ty] = true; //判断可以走,此步状态改为true ,即可走到此步
                    q.push(node_02(tx,ty,now.d + 1));  //搜索
                    //    cout << now.d  <<endl;//?
                }
            }
        }
    }
    return -1; //没有找到
}

void test_02() {
    cin >> n_02 >> m_02;
    for(int i = 0; i < n_02; i++) {
        cin >> maze_02[i] ;
    }
    /*测试
        for(int i = 0; i < n_02; i++) {
        cout << maze_02[i] <<endl;
    }*/
    int x,y;
    for(int i = 0; i < n_02; i++) {
        for(int j = 0; j < m_02; j++) {
            if(maze_02[i][j] == 'S') {  //找起点    ( == 等于 !!! 第二次调试半天 输出x,y值不对发现)
                x = i;
                y = j;

            }
        }
    }

    cout<< bfs_02(x,y) <<endl;
    return;
}

坐标移动


长度为n的坐标轴,从A点移动到B点 ,遵循以下规则
1.向前一步 ,坐标增加1
2.向后一步,坐标减少1
3.跳跃一步,坐标乘2

第一行输入  n,A,B  //分别代表坐标轴长度,起点坐标,终点坐标  [0,5000]
输出最小步数

样例输入:
10 2 7

输出:
3


queue<pair<int,int > > q;  //第二次q可能不空就退出,要手动清,才再次进行遍历 
bool vis[5005];
void test_03() {
    int n,A,B,now,step;  //now现在位置    step步数 
    scanf("%d%d%d",&n,&A,&B);
    q.push(make_pair(A,0));  //now + 1,step + 1
    vis[A] = true;
    while(!q.empty()) {
        now = q.front().first;    //当前 
        step = q.front().second;  //下一步   
        q.pop();
        if(now == B){   //结束 
            cout<< step << endl;
            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;
            //测试cout<<2; 
        }
    }
}

密码锁


 
四位密码 ,每位均为1-9中的一个
当9 加 1 时将变为1,当1减1时变回9  (环形)

第一行输入4位数,表示密码锁的初始状态
第二行输入4位数 ,表示开锁的密码

输出一个整数,表示最小步骤 (用BFS)

样例输入:
1234
2144
输出: 

#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
/*
using namespace std;
struct node{
    int num[4],step;
}first,second;
int vis[11][11][11][11s];
void bfs(){
    int i;
    node a,next;
    queue<node> q;
    a =first;
    a.step;    
}
void test_04(){
    int i,j,t;
    char s1[10],s2[10];
    scanf("%s%s",s1,s2); //字符串读入 
    for(i = 0;i < 4;i++){ //转成数字 
        first.num[i] = s1[i] - '0';
        last.num[i] = s2[i] - '0';
    }
    bfs();
    return;
} 

过于长之后补充  21  ...

 草地 、跳棋 、 魔方还原 、 吃糖 、回家最短路线 、 


void test_04(){
    return;
}
int main() {
    test_03();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值