第一行两个整数n, m,为迷宫的长宽。
接下来n行,每行m个数,数之间没有间隔,为0或1中的一个。0表示这个格子可以通过,1表示不可以。假设你现在已经在迷宫坐标(1,1)的地方,即左上角,迷宫的出口在(n,m)。每次移动时只能向上下左右4个方向移动到另外一个可以通过的格子里,每次移动算一步。数据保证(1,1),(n,m)可以通过。
接下来n行,每行m个数,数之间没有间隔,为0或1中的一个。0表示这个格子可以通过,1表示不可以。假设你现在已经在迷宫坐标(1,1)的地方,即左上角,迷宫的出口在(n,m)。每次移动时只能向上下左右4个方向移动到另外一个可以通过的格子里,每次移动算一步。数据保证(1,1),(n,m)可以通过。
输出格式
第一行一个数为需要的最少步数K。
第二行K个字符,每个字符∈{U,D,L,R},分别表示上下左右。如果有多条长度相同的最短路径,选择在此表示方法下字典序最小的一个。
第二行K个字符,每个字符∈{U,D,L,R},分别表示上下左右。如果有多条长度相同的最短路径,选择在此表示方法下字典序最小的一个。
样例输入
Input Sample 1:
3 3
001
100
110
Input Sample 2:
3 3
000
000
000
3 3
001
100
110
Input Sample 2:
3 3
000
000
000
样例输出
Output Sample 1:
4
RDRD
Output Sample 2:
4
DDRR
4
RDRD
Output Sample 2:
4
DDRR
#include<iostream>
#include<queue>
#include<string>
using namespace std;
struct Node
{
int x; //坐标x
int y; //坐标y
Node *P; //存储前一节点地址
char d; //移动方向
};
typedef Node direct;
const direct D[4] = { { 1, 0 },{ 0, 1 },{ -1, 0 },{ 0, -1 } }; //下右上左
const char Dir[4] = { 'D','R','U','L' }; //方向
//全局变量
int n, m; //迷宫长和宽
int **pic; //迷宫图 1为边界
int **visit; //0表示为访问 1表示已访问
Node **Parent; //存储每一个结点
string short_path = ""; //最短路径
void input() //输入函数
{
cin >> n >> m;
pic = new int*[n + 2]; //迷宫数组
visit = new int*[n + 2];//访问数组
Parent = new Node*[n + 2];
//P_Node = new Node*[n + 2]; //结点数组
for (int i = 0; i < n + 2; i++)
{
pic[i] = new int[m + 2];
visit[i] = new int[m + 2];
Parent[i] = new Node[m + 2];
}
//迷宫初始化,访问数组初始化
for (int i = 0; i < n + 2; i++)
for (int j = 0; j < m + 2; j++)
{
pic[i][j] = 1;
visit[i][j] = 0;
}
char temp;
for (int i = 1; i <= n; i++) //数据输入,在迷宫中心输入,保留迷宫外墙
for (int j = 1; j <= m; j++)
{
if ((temp = getchar()) != '\n')
pic[i][j] = temp - '0';
else
j--;
}
}
bool check(int x, int y) //检验坐标合法性
{
if (visit[x][y] || pic[x][y]) //如果该点已被访问 或该点为1(障碍)
return false; //不合法
return true;
}
string Get_path() //获得路径和总步数
{
int step = 0; //步数
string path = ""; //路径
Node *Par;
path = Parent[n][m].d + path; //获取终点方向
Par = Parent[n][m].P; //获取终点的父指针
for (;;) //循环找每个结点的父节点
{
step++; //每次循环代表回退一步
path = Par->d + path; //从终点向起点遍历父节点,所以方向符号放到字符串末尾
if (Par->x == 1 && Par->y == 1) break; //如果父节点为起点退出
Par = Par->P; //获取该结点的父节点
}
path[0] = step + '0'; //第一位保存路径长度
return path;
}
void BFS()
{
queue<Node> Q; //定义队列
Node start = { 1, 1, NULL,'S' }; //起点
Node end = { n, m }; //终点
Node now, next; //记录当前和下一步
visit[start.x][start.y] = 1; //访问数组状态改变
Q.push(start); //起点入队
while (!Q.empty()) //队列非空
{
now = Q.front(); //队首出队
Parent[now.x][now.y] = now; //当前结点存入数组
Q.pop(); //删除队首
if (now.x == end.x&&now.y == end.y) //如果到达终点则找到路径
{
if (short_path == "") //如果为第一条路径
short_path = Get_path(); //获取路径存入全局变量
else
short_path = (Get_path() < short_path) ? Get_path() : short_path;
//比较选择步数少的路径,如果相同则选取方向按字典序排列较小的
}
for (int i = 0; i < 4; i++)
{
//获取下一步动作
next.x = now.x + D[i].x;
next.y = now.y + D[i].y;
next.P = &Parent[now.x][now.y]; //父指针指向当前地址
if (check(next.x, next.y)) //如果下一步合法
{
visit[next.x][next.y] = 1;
next.d = Dir[i]; //存储移动方向
Q.push(next); //入队
}
}
}
}
int main()
{
input(); //输入
BFS();
int step = short_path[0] - '0'; //获取步数
short_path = short_path.substr(1, short_path.length() - 1); //获取路径
cout << step << endl; //输出步数
cout << short_path << endl; //输出路径
for (int i = 0; i < n; i++)
{
delete[]pic[i];
delete[]visit[i];
delete[]Parent[i];
}
delete[]pic;
delete[]visit;
delete[]Parent;
return 0;
}
但是好像还是有问题实在找不到了 求大神指点