首页 > 其他分享 >刷题日记——干碎那个BFS!(含国科大机试2021)

刷题日记——干碎那个BFS!(含国科大机试2021)

时间:2024-03-18 19:30:49浏览次数:20  
标签:temp field int BFS start 2021 机试 include

例题小引——迷宫问题

问题描述:

迷宫由n行m列的单元格组成(n,m都小于等于50),每个单元格要么是空地,要么是障碍物。
现请你找到一条从起点到终点的最短路径长度。
在这里插入图片描述

分析——(迷宫问题BFS解法)

  1. 使用BFS算法,进行广度优先遍历,总体思路是访问一个结点,就把相邻的结点入队,然后下一个访问的结点就是队首结点,依此循环到终点
  2. 相邻结点的判断:由于上述迷宫只能上下左右四个方向,因此设计坐标轴,上下左右按照坐标增减来确定坐标

代码

#include <bits/stdc++.h>

using namespace std;

int field[100][100];
bool visited[100][100]={false};

struct point{
  int x;
  int y;
  int step;
};

queue<point> info;//结点信息队列

int direct_x[4] = {-1,1,0,0};//方向:上下左右
int direct_y[4] = {0,0,-1,1};

int main()
{
    //输入
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
      for(int j=1;j<=m;j++){
        scanf("%d",&field[i][j]);
      }
    }
    int start_x,start_y,end_x,end_y;
    scanf("%d%d%d%d",&start_x,&start_y,&end_x,&end_y);

    //BFS
    point start;
    start.step = 0;
    start.x = start_x;
    start.y = start_y;

    info.push(start);

    visited[start_x][start_y] = true;

    bool flag = false;

    while(info.empty()!=true){
      int x = info.front().x;
      int y = info.front().y;
      if(x==end_x&&y==end_y){
        printf("%d\n",info.front().step);
        flag = true;
        break;
      }
      for(int i=0;i<4;i++){
        int temp_x = x+direct_x[i];
        int temp_y = y+direct_y[i];
        if(field[temp_x][temp_y]==1&&visited[temp_x][temp_y]==false){
          point temp;
          temp.x = temp_x;
          temp.y = temp_y;
          temp.step = info.front().step +1;
          info.push(temp);
          visited[temp_x][temp_y]==true;
        }
      }
      info.pop();//队首出队
    }
    if(flag==false){
      printf("no way");
    }
    return 0;
}

迷宫问题使用BFS的总结

需要定义的重要数组

  • 迷宫地图:二维数组 f i e l d [ m ] [ n ] field[m][n] field[m][n],其中 m m m是行数, n n n是列数
  • 已访问标记:二维bool数组 v i s i t e d [ m ] [ n ] visited[m][n] visited[m][n]
  • 地址信息:结构体,需要包含该地址的横纵坐标和到达此处走的步数
  • 指路队列:以地址信息为数据类型的队列,每次离开一个地址之前,先要把接下来能够去的地址信息入队
  • 方向数组:两个数组 d i r e c t x [ w a y s ] direct_x[ways] directx​[ways]和 d i r e c t y [ w a y s ] direct_y[ways] directy​[ways],ways表示在一个地址处能够移动的方向个数,数组存的是如果按照这个方向走,其横纵坐标变化情况

初始化

  • 输入迷宫信息初始化迷宫地图
  • 根据出发点信息,创建地址信息结点加入队列,初始时的步数是0
  • 初始时地图上所有结点都未访问,访问标记设为false

BFS启动

  1. 当指路队列非空时,重复操作1~4,如果空,跳到5.
  2. 根据指路队列首结点,即当前的位置(横纵坐标),判断是否到达终点,如果到达跳到5.,没有到达执行3
  3. 遍历查看所有的ways个方向指向的地址能不能到达,如果可以到达,那么将该地址入队
  4. 所有能走的路都计入队列后,离开当前地址,跳到1.
  5. 判断:如果是从1跳过来的,说明终点不可达;如果是从2跳过来的,说明终点可达,且当前队首所指地址信息的步数就是从起点到终点的总步数

小试牛刀——石油储藏(中国科学院大学2021年机试题)

在这里插入图片描述

分析

  • 按照行列顺序遍历地图,一旦找到‘@’,那么就以此地址作为起点,进行BFS:
  • BFS:对于沿途所有能到达的地址,如果该地址是‘@’,那么就置为’*',同时设置为已访问
  • 每完成一次BFS就表明一个连续的油田已经被勘测完毕,油田计数器+1
  • 遍历完地图,油田计数器值即为地图上油田数

代码

#include <cstdio>
#include <map>
#include <string>
#include <string.h>
#include <cmath>
#include <vector>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <limits.h>
using namespace std;
char field[101][101];
bool visited[101][101]={false};

struct address{
  int x;
  int y;
};

int direct_x[8] = {-1,-1,-1,0,1,1, 1, 0};
int direct_y[8] = {-1, 0, 1,1,1,0,-1,-1};

queue<address> instructor;


void BFS(int x, int y){
  address start;
  start.x = x;
  start.y = y;
  field[x][y] = '*';
  visited[x][y] = true;
  instructor.push(start);
  while(instructor.empty()!=true){
    int x = instructor.front().x;
    int y = instructor.front().y;
    for(int i=0;i<8;i++){
      int temp_x = x+direct_x[i];
      int temp_y = y+direct_y[i];
      if(field[temp_x][temp_y]=='@'&&visited[temp_x][temp_y]==false){
        address temp;
        temp.x = temp_x;
        temp.y = temp_y;
        field[temp_x][temp_y]='*';
        visited[temp_x][temp_y]=true;
        instructor.push(temp);
      }
    }
    instructor.pop();
  }
}

int main(){
  int m,n;
  while(true){
    scanf("%d%d  ",&m,&n);
    if(m==0&&n==0){
      break;
    }
    for(int i=1;i<=m;i++){
      for(int j=1;j<=n;j++){
        scanf("%c",&field[i][j]);
        visited[i][j]=false;//多次输入,随输入进行初始化
      }
      scanf("%c",&field[i][0]);
    }
    /*for(int i=1;i<=m;i++){
      for(int j=1;j<=n;j++){
        printf("%d\t%d\t%c\n",i,j,field[i][j]);
      }
      printf("\n");
    }*/

    int counts = 0;
    for(int i=1;i<=m;i++){
      for(int j=1;j<=n;j++){
        if(field[i][j]=='@'){
          BFS(i,j);
          counts++;
        }
      }
    }
    printf("%d\n",counts);

  }

	return 0;
}

标签:temp,field,int,BFS,start,2021,机试,include
From: https://blog.csdn.net/qq_48035645/article/details/136787272

相关文章

  • 华为OD机试Java - 机器人搬砖
    机器人搬砖前言:本专栏将持续更新互联网大厂机试真题,并进行详细的分析与解答,包含完整的代码实现,希望可以帮助到正在努力的你。关于大厂机试流程、面经、面试指导等,如有任何疑问,欢迎联系我,wechat:steven_moda;email:[email protected];备注:CSDN。题目描述机器人搬砖,一共有N......
  • 华为OD机试Java - 转盘寿司
    转盘寿司前言:本专栏将持续更新互联网大厂机试真题,并进行详细的分析与解答,包含完整的代码实现,希望可以帮助到正在努力的你。关于大厂机试流程、面经、面试指导等,如有任何疑问,欢迎联系我,wechat:steven_moda;email:[email protected];备注:CSDN。题目描述寿司店周年庆,正在举办......
  • 华为OD机试Java - 分月饼
    分月饼前言:本专栏将持续更新互联网大厂机试真题,并进行详细的分析与解答,包含完整的代码实现,希望可以帮助到正在努力的你。关于大厂机试流程、面经、面试指导等,如有任何疑问,欢迎联系我,wechat:steven_moda;email:[email protected];备注:CSDN。题目描述中秋节,公司分月饼,m个员......
  • bfs判重的坑
    在\(bfs\)中判重时,应优先在入队时进行判重,而不是在出队时进行判重,因为一个节点\(u\)在入队到出队的过程中,可能需要先出队很多其他节点\(v\),这就会导致其他节点出队且加入新节点的过程中,可能会重复加入多次节点\(u\),进而导致\(queue\)占用的空间过大,最后可能有几个点\(MLE......
  • 中考英语首字母快速突破009-2021上海闵行英语二模-Preventing and Managing Stomach F
    PDF格式公众号回复关键字:ZKSZM009原文​Stomachfluisacommondisease.Itspreadseasily,whichmakesithardtoavoid.That'se(71)trueifsomeoneinyourfamilyhasit.Stomachfluiscausedbyavirus,butnotthesameonethatcausesregular......
  • 中国电子学会(CEIT)2021年03月真题C语言软件编程等级考试四级(含详细解析答案)
    中国电子学会(CEIT)考评中心历届真题(含解析答案)C语言软件编程等级考试四级2021年03月编程题四道 总分:100分一、酒鬼(25分)Santo刚刚与房东打赌赢得了一间在NewClondike的大客厅。今天,他来到这个大客厅欣赏他的奖品。房东摆出了一行瓶子在酒吧上。瓶子里都装有不......
  • c++机试一些提示
    1、优先队列的使用,头文件#include;优先队列定义:priority_queue<int,vector<int>,greater<int>>pq;(整数数据类型,小顶堆)。例题:哈夫曼树#include<iostream>#include<queue>usingnamespacestd;intmain(){intn;cin>>n;priority_queue<i......
  • 华为OD机试 C++ -文件缓存系统
    文件缓存系统前言:本专栏将持续更新互联网大厂机试真题,并进行详细的分析与解答,包含完整的代码实现,希望可以帮助到正在努力的你。关于大厂机试流程、面经、面试指导等,如有任何疑问,欢迎联系我,wechat:steven_moda;email:[email protected];备注:CSDN。题目描述请设计一个文件缓......
  • 华为OD机试Js - 文件缓存系统
    文件缓存系统前言:本专栏将持续更新互联网大厂机试真题,并进行详细的分析与解答,包含完整的代码实现,希望可以帮助到正在努力的你。关于大厂机试流程、面经、面试指导等,如有任何疑问,欢迎联系我,wechat:steven_moda;email:[email protected];备注:CSDN。题目描述请设计一个文件缓......
  • 华为OD机试Js - 高效货运
    高效货运前言:本专栏将持续更新互联网大厂机试真题,并进行详细的分析与解答,包含完整的代码实现,希望可以帮助到正在努力的你。关于大厂机试流程、面经、面试指导等,如有任何疑问,欢迎联系我,wechat:steven_moda;email:[email protected];备注:CSDN。题目描述老李是货运公司承运人......