目录
P1443 马的遍历
BFS
DFS (错误代码)
P1443 马的遍历
- 评测方式云端评测
- 标签
- 难度普及/提高-
- 时空限制1000ms / 128MB
题目描述
有一个n*m的棋盘(1
输入输出格式
输入格式:
一行四个数据,棋盘的大小和马的坐标
输出格式:
一个n*m的矩阵,代表马到达某个点最少要走几步(左对齐,宽5格,不能到达则输出-1)
输入输出样例
输入样例#1: 复制
3 3 1 1
输出样例#1: 复制
0 3 2
3 -1 1
2 1 4
BFS
思路:
就是八个方向遍历
代码:
#include
using namespace std;
const int N=401;
int n,m,sx,sy; //棋盘的大小和马的坐标
int dir[][2]={{-2,-1},{-1,-2},{1,-2},{2,-1},{-2,1},{-1,2},{1,2},{2,1}};
int vis[N][N];
struct node
{
int x,y;
}pre,nex;
int step[N][N]; //存储步数
void bfs(int x,int y,int s)
{
queue Q;
pre.x=x; //初始化pre
pre.y=y;
step[x][y]=s;
vis[x][y]=1; //初始化起点为已访问
Q.push(pre); //入队
while(!Q.empty())
{
nex=Q.front(); //nex获取队首元素
Q.pop(); //出队
for(int i=0;i<8;i++) //第一次执行for 找出所有可以一步到达的坐标 第二次找出能2步到达的各个坐标
{
int xx=nex.x+dir[i][0];
int yy=nex.y+dir[i][1];
if(xx<=0||xx>n||yy<=0||yy>m) //越界检查
continue;
if(!vis[xx][yy]) //每个坐标只入队一次
{
vis[xx][yy]=1;
pre.x=xx; //用另外一个结构体存储新的坐标
pre.y=yy;
Q.push(pre); //新的坐标入队
step[xx][yy]=step[nex.x][nex.y]+1; //步数是上一个坐标的步数加一
}
}
}
}
int main()
{
std::ios::sync_with_stdio(false);
memset(step,-1,sizeof(step)); //初始化
memset(vis,0,sizeof(vis));
cin>>n>>m>>sx>>sy;
bfs(sx,sy,0); //初始步数为0
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
printf("%-5d",step[i][j]); //输出
}
printf("\n");
}
return 0;
}
DFS
错误代码........
#include
using namespace std;
const int N=401;
int n,m,sx,sy; //棋盘的大小和马的坐标
int step[N][N];
int dir[][2]={{-2,-1},{-1,-2},{1,-2},{2,-1},{-2,1},{-1,2},{1,2},{2,1}};
int vis[N][N];
void bfs(int x,int y,int move) //move为移动的次数
{
if(move>200) //200的阈值到达极限
return ;
if(step[x][y]!=-1)
step[x][y]==min(move,step[x][y]);
else
step[x][y]=move;
for(int i=0;i<8;i++)
{
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(xx<=0||xx>n||yy<=0||yy>m)
continue;
if(!vis[xx][yy])
{
vis[xx][yy]=1;
bfs(xx,yy,move+1);
}
}
}
int main()
{
std::ios::sync_with_stdio(false);
memset(step,-1,sizeof(step));
memset(vis,0,sizeof(vis));
cin>>n>>m>>sx>>sy;
bfs(sx,sy,0);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
printf("%-5d",step[i][j]);
}
printf("\n");
}
return 0;
}