P1443 马的遍历

题目描述

有一个n*m的棋盘(1

输入格式

一行四个数据,棋盘的大小和马的坐标

输出格式

一个n*m的矩阵,代表马到达某个点最少要走几步(左对齐,宽5格,不能到达则输出-1)

输入样例

3 3 1 1

输出样例

0    3    2    
3    -1   1    
2    1    4    

题解

#include
using namespace std;
struct Position //坐标,用于队列存储
{
    int x,y;
}node,top;
const int maxN = 405, maxM = 405;
int matrix[maxN][maxM],dir[8][2] = {{2,1},{2,-1},{1,2},{1,-2},{-1,2},{-1,-2},{-2,1},{-2,-1}};//matrix数组存储棋盘步数 dir数组存储方向
int n,m;
bool flag[maxN][maxN];//标记某位置已被搜索过

void Search(int x, int y, int step)
{
    //对起点进行标记
    matrix[x][y] = step;
    flag[x][y] = true;
    //将起点入队
    node.x = x;
    node.y = y;
    queue Q;
    Q.push(node);
    //开始搜索
    while(!Q.empty())
    {
        //取队首坐标并离队
        top = Q.front();
        Q.pop();
        //遍历八个方向
        for(int i = 0; i < 8; i++)
        {
            int tx = top.x + dir[i][0];
            int ty = top.y + dir[i][1];
            if(tx < 1 || tx > n || ty < 1 || ty > m) continue;//越界判断
            if(!flag[tx][ty])//判断是否搜过该坐标
            {
                node.x = tx;
                node.y = ty;
                Q.push(node);//入队
                //标记该坐标
                matrix[tx][ty] = matrix[top.x][top.y] + 1;
                flag[tx][ty] = true;
            }
        }
    }
}
int main()
{
    int x,y;
    scanf("%d %d %d %d",&n,&m,&x,&y);
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            matrix[i][j] = -1;
        }
    }
    Search(x,y,0);
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            printf("%-5d",matrix[i][j]);//注意输出格式
        }
        printf("\n");
    }
    return 0;
}

总结

这道题一开始我并没有想到BFS,所以有两个测试点超时了。看了别人的题解才知道了思路:用队列来规定搜索的顺序,保证先搜完每一层的坐标再往下一层搜索。其实这道题的解决思路还是比较容易想的,从起点出发,按方向进行搜索,直到搜完整个棋盘,也能想到用标记数组来减少搜索的次数,但是什么时候进行标记是一个问题。这里我奉上我的超时代码。

错误题解

import java.util.Scanner;

public class P1443 {

	public static int[][] matrix = new int[405][405];
	public static int m,n;
	public static int[][] dir = new int[][] {{2,1},{2,-1},{1,2},{1,-2},{-1,2},{-1,-2},{-2,1},{-2,-1}};
	public static void Search(int x, int y, int step) {
		if (x < 1 || x > n || y < 1 || y > m ) {
			return;
		}else {
			if (matrix[x][y] == -1) {
				matrix[x][y] = step;
			}else{
				if (matrix[x][y] > step) {
					matrix[x][y] = step;
				}else {
					return;
				}
			}
			step++;
			for(int i = 0; i < 8; i++) {
				Search(x + dir[i][0], y + dir[i][1], step);
			}
		}
		return;
	}
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Scanner scanner = new Scanner(System.in);
		n = scanner.nextInt();
		m = scanner.nextInt();
		int x = scanner.nextInt();
		int y = scanner.nextInt();
		for(int i = 1; i <= n; i++) {
			for(int j = 1; j <= m; j++) {
				matrix[i][j] = -1;
			}
		}
		Search(x, y, 0);
		for(int i = 1; i <= n; i++) {
			for(int j = 1; j <= m; j++) {
				System.out.printf("%-5d",matrix[i][j]);
			}
			System.out.println();
		}
		scanner.close();
	}

}

 

你可能感兴趣的:(学习,JAVA,C++,洛谷)