原题链接:蓝桥杯2015年第六届真题-穿越雷区
解题思路:
利用广搜算法来做这题,一般像这种二维数组的地图,让你走去一个地方,求最短路程都可以用深搜或者广搜,不过地图一旦大了,那么深搜就较为容易超时的,看情况来吧,地图小,深搜和广搜都可以,地图大了,还是建议广搜好一点
注意事项:
广搜的特点就是,记录起点坐标,以起点为head,遍历上下左右四个方向的地点,符合条件的地点则存储,然后tail++,不符合就不存储进来。遍历4个方向后,head++,以新的head为起点,再次遍历四个方向,符合的tail++,不符合的就下一个方向遍历,直至4个方向都尝试过了。然后又是head++.......,如此反复的一个过程
如:
3 A + - + - + + - B 可以看出答案是4对吧,A-----》(1,2)-----》(2,2)-----》(2,3)-----》B 一共四步 或者 A-----》(1,2)-----》(1,3)-----》(2,3)-----》B 一共四步 我就选第一个来说吧 一开始,在输入过程中就记录下A的坐标位置了,然后从A的四个方向遍历,符合条件就存储,tail++,不符合就不存储 h表示head,t表示tail,第四行数字表示步数 n数组xiabi下标1-m*m 第一次遍历,head(A)的位置(1,1),因为符合的只有(1,2)和(2,1) h t 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A 12 21 0 1 1 第二次遍历,head的位置(1,2),因为符合的只有(1,3)和(2,2) h t 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A 12 21 31 22 0 1 1 2 2 第三次遍历,head的位置(2,1)没有符合条件的 h t 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A 12 21 31 22 0 1 1 2 2 第四次遍历,head的位置(3,1),因为符合的只有(2,3) h t 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 A 12 21 31 22 23 0 1 1 2 2 3 .........下面的步骤我就不写了,慢慢理解一下
参考代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string.h>
#include<math.h>
#include<string>
#include<algorithm>
#include<functional>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<iomanip>
using namespace std;
//地图
char mmap[150][150];
//标技数组,就走过的地点就不再重复走了
bool book[150][150];
//方向数组,控制方向,我的顺序是右下左上
int nnext[4][2] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
//判断走不到终点的时候,就输出-1的标志变量,ff=false则说明可以走到B,ff=true则走不到B
bool ff = false;
//广搜用来存放每一步可以走的结构体数组,包含坐标,步数,和字符符号,因为+-才能走,++和--都不行,是用来存储字符比较下一步可不可以走的
typedef struct node{
int x, y, step;
char flag;
}node;
node n[10200];//广搜数组一般大小为m*m,因为最大是100,也就是100*100=10000,我开大一点
int main(){
//m*m地图
int m;
cin >> m;
getchar();//输入m后,吃掉回车
int head, tail,x,y,tx,ty;
for (int i = 1; i <= m; i++){
for (int j = 1; j <= m; j++){
scanf("%c", &mmap[i][j]);
if (mmap[i][j] == 'A'){//记录起点位置,记下坐标
x = i, y = j;
}
getchar();//吃掉空格和换行的回车
}
}
//初始化
head = tail = 1;//广搜实质上可以理解成一个队列,头和尾
n[tail].x = x; n[tail].y = y; n[tail].step = 0; n[tail].flag = ' ';
book[x][y] = 1;//标记起点位置A,说明待会广搜的话就不会再走回来起点A的位置
tail++;
//广搜的核心
while (head < tail){
for (int i = 0; i < 4; i++){
tx = n[head].x + nnext[i][0];
ty = n[head].y + nnext[i][1];
//边界,超过地图边界,就不会走
if (tx > m || tx < 1)continue;
if(ty > m || ty < 1)continue;
//没去过的地点,而且符合一正一负
if (book[tx][ty] == 0 && n[head].flag != mmap[tx][ty]){
book[tx][ty] = 1;
n[tail].y = ty;
n[tail].x = tx;
n[tail].step = n[head].step+1;//步数等于上一步的步数+1
n[tail].flag = mmap[tx][ty];
tail++;
}
}
if (n[head].flag == 'B'){
cout << n[head].step;
ff = true;
break;
}
head++;
}
if (!ff)cout << -1;
system("pause");
return 0;
}0.0分
6 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复