时限:1000ms 内存限制:10000K 总时限:3000ms
描述
判断是否能从迷宫的入口到达出口
输入
先输入两个不超过20的正整数表示迷宫的行数m和列数n,再输入口和出口的坐标,最后分m行输入迷宫,其中1表示墙,0表示空格每个数字之间都有空格。
输出
只能向上、下、左、右四个方向走若能到达,则输出"Yes",否则输出"No",结果占一行。
输入样例
3 3
0 0
2 2
0 0 0
1 1 0
0 1 0
输出样例
Yes
#include
using namespace std;
int m,n;
int sx,sy; //start
int tx,ty; //target
int maze[20][20];
int walk[2][4]={ //4个方向对应的行列坐标变化
0, +1, 0, -1, //行坐标:左、下、右、上
-1, 0, +1, 0 //列坐标:左、下、右、上
};
void bfs(int x, int y); //深搜,搜到的每个地方都标记-1
bool canmoveto(int x, int y, int i); //判断能否向i方向走一格
int main()
{
cin>>m>>n;
cin>>sx>>sy;
cin>>tx>>ty;
for(int i=0; i>maze[i][j];
}
}
bfs(sx, sy);
if(maze[tx][ty]==-1)
{
cout<<"Yes"<=m) //行数越界
{
return false;
}
if(y+walk[1][i]<0 || y+walk[1][i]>=n) //列数越界
{
return false;
}
if(maze[x+walk[0][i]][y+walk[1][i]]!=0) //是墙或重复
{
return false;
}
return true;
}
【后记】
1.第二次写这个,深深感觉到初学算法的自己是多么图样图森破。。。
2.本题中,maze存储迷宫,0表示空,1表示墙,-1表示这个格子搜过,如果bfs结束后出口处格子为-1,证明能够到达
按照惯例,要搜的4个方向用数字表示,0==左,1==下,2==右,3==上
3.昨天看了一个同学的代码,学会了下面这招,直接bfs到下一个要搜的格子,妈妈再也不用担心我写switch(i)判断方向返回新格子的坐标写到手断了……
int walk[2][4]={ //4个方向对应的行列坐标变化
0, +1, 0, -1, //行坐标:左、下、右、上
-1, 0, +1, 0 //列坐标:左、下、右、上
};
//中间代码略
void bfs(int x, int y)
{
maze[x][y]=-1; //标记到达
for(int i=0; i<4; i++) //向4个方向搜索
{
if(canmoveto(x, y, i))
{
bfs(x+walk[0][i], y+walk[1][i]); //数组真好用!
}
}
}