1042.电子老鼠闯迷宫
时限:1000ms 内存限制:10000K 总时限:3000ms
描述
有一只电子老鼠被困在如下图所示的迷宫中。这是一个12*12单元的正方形迷宫,黑色部分表示建筑物,白色部分是路。电子老鼠可以在路上向上、下、左、右行走,每一步走一个格子。现给定一个起点S和一个终点T,求出电子老鼠最少要几步从起点走到终点。(迷宫左上角为[1, 1])
输入
本题包含一个测例。在测例的第一行有四个由空格分隔的整数,分别表示起点的坐标S(x.y)和终点的坐标T(x,y)。
从第二行开始的12行中,每行有12个字符,描述迷宫的情况,其中'X'表示建筑物,'.'表示路.
输出
输出一个整数,即电子老鼠走出迷宫至少需要的步数。
#include <iostream>
#include <queue>
using namespace std;
struct Node //用一个结构体存放当前在迷宫中的位置/状态
{
int x; //当前状态横坐标,从1开始
int y; //当前状态纵坐标,从1开始
};
queue <Node> state; //结构体队列
//这是自己写的第一个结构体队列,值得纪念,液!
char maze[13][13]; //存放迷宫,从[1,1]开始
int used[13][13]; //当前格子是否已访问过
int step[13][13]; //存放从起点走到当前格子需要走的步数
bool canmoveto(int x,int y,int d); //判断方格[x,y]能否向方向d走一步
Node moveto(int x,int y,int d); //返回方格[x,y]向d走一步之后到达的格子node
int main()
{
Node start,target; //起点结构体与终点结构体
cin>>start.x>>start.y>>target.x>>target.y;
for(int i=1;i<=12;i++)
{
for(int j=1;j<=12;j++)
{
cin>>maze[i][j];
}
}
state.push(start); //起点入队
used[start.x][start.y]=1; //标记起点访问过
step[start.x][start.y]=0; //从起点走到起点需要0步
Node top,next;
while(!state.empty())
{
top=state.front(); //取队首元素
state.pop();
for(int d=0; d<4; d++) //向四个方向试探
{
if(canmoveto(top.x,top.y,d)) //如果方向d能走
{
next=moveto(top.x,top.y,d); //向方向d走一步,走到next格子
used[next.x][next.y]=1; //标记next格子被访问过
step[next.x][next.y]=step[top.x][top.y]+1; //走到next格子的步数比走到top格子的步数多一步
state.push(next); //将next入队
if(next.x==target.x&&next.y==target.y) //如果next格子就是目标格子,那么退出
{
break;
}
//cout<<next.x<<' '<<next.y<<' '<<step[next.x][next.y]<<endl;
}
}
if(next.x==target.x&&next.y==target.y) //如果next格子就是目标格子,那么退出
{
break;
}
}
cout<<step[target.x][target.y]<<endl;
return 0;
}
//不能走的条件:越界、为墙、已访问过
bool canmoveto(int x,int y,int d) //判断方格[x,y]能否向方向d走一步
{
switch(d)
{
case 0: //左
{
if(y-1<1||maze[x][y-1]=='X'||used[x][y-1]==1)
{
return false;
}
else
{
break;
}
}
case 1: //下
{
if(x+1>12||maze[x+1][y]=='X'||used[x+1][y]==1)
{
return false;
}
else
{
break;
}
}
case 2: //右
{
if(y+1>12||maze[x][y+1]=='X'||used[x][y+1]==1)
{
return false;
}
else
{
break;
}
}
case 3: //上
{
if(x-1<1||maze[x-1][y]=='X'||used[x-1][y]==1)
{
return false;
}
else
{
break;
}
}
}
return true;
}
Node moveto(int x,int y,int d) //返回方格[x,y]向d走一步之后到达的格子node
{
Node next;
switch(d)
{
case 0: //左
{
next.x=x;
next.y=y-1;
break;
}
case 1: //下
{
next.x=x+1;
next.y=y;
break;
}
case 2: //右
{
next.x=x;
next.y=y+1;
break;
}
case 3: //上
{
next.x=x-1;
next.y=y;
break;
}
}
return next;
}
【后记】
1.代码写到现在,写的第一个结构体队列!作为一个当初自己瞎啃数据结构被难到哭泣的人,开森!
2.写完之后,虽然AC了,但还是发现不对,因为在while循环里套了一个for循环,所以判断到达目标状态后应该break两次,虽然有些繁琐,但还是暂且这样加在代码里。之前只有一个break的时候居然能通过,充分说明了noj的测例还是太宽松。