算法提高 学霸的迷宫
时间限制:1.0s 内存限制:256.0MB
问题描述
学霸抢走了大家的作业,班长为了帮同学们找回作业,决定去找学霸决斗。但学霸为了不要别人打扰,住在一个城堡里,城堡外面是一个二维的格子迷宫,要进城堡必须得先通过迷宫。因为班长还有妹子要陪,磨刀不误砍柴功,他为了节约时间,从线人那里搞到了迷宫的地图,准备提前计算最短的路线。可是他现在正向妹子解释这件事情,于是就委托你帮他找一条最短的路线。
输入格式
第一行两个整数n, m,为迷宫的长宽。
接下来n行,每行m个数,数之间没有间隔,为0或1中的一个。0表示这个格子可以通过,1表示不可以。假设你现在已经在迷宫坐标(1,1)的地方,即左上角,迷宫的出口在(n,m)。每次移动时只能向上下左右4个方向移动到另外一个可以通过的格子里,每次移动算一步。数据保证(1,1),(n,m)可以通过。
输出格式
第一行一个数为需要的最少步数K。
第二行K个字符,每个字符∈{U,D,L,R},分别表示上下左右。如果有多条长度相同的最短路径,选择在此表示方法下字典序最小的一个。
样例输入
Input Sample 1:
3 3
001
100
110
Input Sample 2:
3 3
000
000
000
样例输出
Output Sample 1:
4
RDRD
Output Sample 2:
4
DDRR
数据规模和约定
有20%的数据满足:1<=n,m<=10
有50%的数据满足:1<=n,m<=50
有100%的数据满足:1<=n,m<=500。
此题竟然需要多组输入。。。,字典序为 D,L,R,U,按照D,L,R,U的顺序移动就行
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
char s[550][550];
int vis[550][550];
int a[4][2]={
1,0,
0,-1,
0,1,
-1,0
};
int n,m,ans;
struct node
{
int x,y;
int step;
}p[maxn];
node pre[550][550]; //记录上一个状态
stack<node> ss;
void bfs(int x,int y)
{
memset(vis,0,sizeof(vis));
queue<node> q;
node w,h;
w.x = x;
w.y = y;
vis[x][y] = 1;
w.step = 0;
q.push(w);
while(!q.empty())
{
w = q.front();
q.pop();
if(w.x==n-1 && w.y==m-1)
{
ans = w.step;
while( !(w.x==0 && w.y==0) )
{
ss.push(w);
w = pre[w.x][w.y];
// printf("%d %d %d\n",w.x,w.y,w.step);
}
ss.push(w);
return ;
}
for(int i=0;i<4;i++)
{
h.x = w.x+a[i][0];
h.y = w.y+a[i][1];
if(!vis[h.x][h.y] && h.x>=0&&h.x<n && h.y>=0&&h.y<m && s[h.x][h.y]!='1')
{
vis[h.x][h.y] = 1;
h.step = w.step+1;
pre[h.x][h.y] = w;
q.push(h);
}
}
}
}
void prin()
{
node w,h;
while(!ss.empty())
{
w = ss.top(); //现在的状态
ss.pop();
if(ss.empty())
break;
h = ss.top(); //下一个状态
if(w.x-1==h.x && w.y==h.y)
printf("U");
else if(w.x+1==h.x && w.y==h.y)
printf("D");
else if(w.x==h.x && w.y-1==h.y)
printf("L");
else if(w.x==h.x && w.y+1==h.y)
printf("R");
}
printf("\n");
}
int main()
{
int k = 1;
while(~scanf("%d%d",&n,&m))
{
while(!ss.empty())
ss.pop();
ans = 0;
for(int i=0;i<n;i++)
scanf("%s",s[i]);
bfs(0,0);
printf("%d\n",ans);
prin();
k++;
}
return 0;
}
JAVA
import java.math.BigInteger;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
public class Main {
static class node
{
int x,y;
int step;
node(){};
node(int x,int y,int step)
{
this.x = x;
this.y = y;
this.step = step;
}
}
static Stack<node> ss = new Stack<node>();
static int n,m,ans;
static int [][]vis = new int[550][550];
static char [][]s = new char[550][550];
static node[][]pre = new node[550][550];
static int a[][] = {
{1,0},
{0,-1},
{0,1},
{-1,0}
};
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner cin = new Scanner(System.in);
String str;
while(cin.hasNext())
{
n = cin.nextInt();
m = cin.nextInt();
while(!ss.empty())
ss.pop();
ans = 0;
for(int i=1;i<=n;i++)
{
str = cin.next();
for(int j=0;j<m;j++)
s[i][j+1] = str.charAt(j);
}
bfs(1,1);
System.out.println(ans);
print();
}
}
public static void bfs(int x,int y)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
vis[i][j]=0;
}
Queue<node> q = new LinkedList<node>();
node w = new node(x,y,0);
q.add(w);
vis[x][y] = 1;
while(!q.isEmpty())
{
w = q.poll();
if(w.x==n && w.y==m)
{
ans = w.step;
while( !(w.x==1 && w.y==1))
{
ss.push(w);
w = pre[w.x][w.y];
}
ss.push(w);
return ;
}
for(int i=0;i<4;i++)
{
node h = new node();
h.x = w.x+a[i][0];
h.y = w.y+a[i][1];
if(vis[h.x][h.y]==0&&h.x>0&&h.x<=n&&h.y>0&&h.y<=m&&s[h.x][h.y]!='1')
{
vis[h.x][h.y] = 1;
h.step = w.step+1;
pre[h.x][h.y] = w;
q.add(h);
}
}
}
}
public static void print()
{
node w = new node();
node h = new node();
while(!ss.empty())
{
w = ss.peek();
ss.pop();
if(ss.empty())
break;
h = ss.peek();
if(w.x-1==h.x && w.y==h.y)
System.out.print("U");
else if(w.x+1==h.x && w.y==h.y)
System.out.print("D");
else if(w.x==h.x && w.y-1==h.y)
System.out.print("L");
else if(w.x==h.x && w.y+1==h.y)
System.out.print("R");
}
System.out.println();
}
}