跳跳 一个每块地板标记着0~9某个数字的迷宫,其中标记1的地板不可以走,标记2~9的地板可以不花时间地跳到任意相同数字的位置,也可以和标记0的地板一样向前后左右任意方向花1个单位时间移动1的距离。给出起点和终点,求起点到终点的最短时间。

我写的博客都是用c语言写的,易懂,重在理解

在做这道题的时候,我很无奈,看着别人做,自己却没思路,很无奈,In a word,一句话,是没有理解好bfs的后果

bfs相当于在头点,上下左右,寻找能走的路,最终以找到终点为目地。

bfs相当于二叉树中的层次遍历,需要用到栈

 一个每块地板标记着0~9某个数字的迷宫,其中标记1的地板不可以走,标记2~9的地板可以不花时间地跳到任意相同数字的位置,也可以和标记0的地板一样向前后左右任意方向花1个单位时间移动1的距离。给出起点和终点,求起点到终点的最短时间。

Input

 每组数据第一行一个n,表示尺寸,2 <= n <= 100。

接下来n行每行n个0~9的字符,或S表示起点,E表示终点,S和E的运动规则与0相同。整个地图只有一个S和一个E。

Output

 每组数据输出一个数,占一行,表示起点到终点可以花费的最短时间。

如果无法到达重点,输出"Oh No!"

5
0S100
00131
00300
00000
003E0
3
S12
010
10E

#include <iostream>
#include <stdio.h>
#include <queue>
#include <string.h>
#define N 110
using namespace std;

int vis[N][N], dis[N][N],a[N][N];
int n,x1,y1,x2,y2;
int dx[4]= {1,-1,0,0};
int dy[4]= {0,0,1,-1};
void bfs(int x3,int y3,int x2,int y2)
{

queue <pair<int ,int > >q; // 这是用的STL中的队列和pair,pair< 存类型>
q.push(make_pair(x3,y3)); // 把坐标放通过pair对,放进队列

vis[x3][y3]=1;   //访问过标记一下

while(!q.empty())
{

int x1,y1;
x1=q.front().first;   // 取出队列中一组pair对的横坐标

y1=q.front().second; // 取出队列中一组pair对的纵坐标
if(x1==x2&&y1==y2)break;  

q.pop();  //清空队列头元素

int i;
for(i=0; i<4; i++)
{

int xx,yy;
xx=x1+dx[i];
yy=y1+dy[i];

if(vis[xx][yy]==0&&a[xx][yy]==0) 
{
vis[xx][yy]=1;
q.push(make_pair(xx,yy));
dis[xx][yy]=1+dis[x1][y1];  // 记录当前层数,即当前步数
}
else if(a[xx][yy]>=2&&a[xx][yy]<=9&&vis[xx][yy]==0)  //假如碰到2和9之间的数x,就把此图中的x全部进入队列
{

vis[xx][yy]=1;
q.push(make_pair(xx,yy));   
dis[xx][yy]=1+dis[x1][y1];  记录步数

for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
if(a[i][j]==a[xx][yy]&&vis[i][j]==0)
{
q.push(make_pair(i,j));   
vis[i][j]=1;
dis[i][j]=dis[xx][yy];  // 因为题目说移到相同数字的方块,不耗费时间,所以不加1
}

}

}

}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
int i,j;
char s[120];
memset(vis,0,sizeof(vis));   //标记是否被访问过
memset(a,1,sizeof(a));    // 转化为迷宫问题
memset(dis,0,sizeof(dis));  // 储存二叉树的层数,即最小的步数到达终点
for(i=0; i<n; i++)
{
scanf("%s",s);
for(j=0; j<n; j++)
{
if(s[j]=='0')a[i+1][j+1]=0;
else if(s[j]>='2'&&s[j]<='9')a[i+1][j+1]=s[j]-'0';   
else if(s[j]=='S')a[i+1][j+1]=0,x1=i+1,y1=j+1;     //处理字符串,把a建成平面图
else if(s[j]=='E')a[i+1][j+1]=0,x2=i+1,y2=j+1;

}
}

bfs(x1,y1,x2,y2);
if(dis[x2][y2]==0)printf("Oh No! ");  //如果不能到达终点,则储存路径的数组中为初始值0
else printf("%d ",dis[x2][y2]);
}

}

原文地址:https://www.cnblogs.com/woyaocheng/p/4725237.html