落谷 P1443 马的遍历

P1443 马的遍历

算法练习

题目描述

有一个n*m的棋盘(1<n,m<=400),在某个点上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步

输入格式

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

输出格式

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

输入输出样例
输入

3 3 1 1

输出

0 3 2
3 -1 1
2 1 4

代码

这题目我首先想到的是DFS而不是BFS,由于我是java做的,用深度优先搜索会超时,有可能是我能力不够,初步学习不知道dfs还可以再剪枝。

以下是我DFS的做法,30分
import java.util.Scanner;

public class Main {
	static int endx, endy, n, m, a, b, ans = Integer.MAX_VALUE;
	static int[][] horse = new int[401][401];//存数
	static int[][] vis = new int[401][401];//标记是否走过
	static int[] xx = {-2,-1,1,2,2,1,-1,-2};//方向数组
	static int[] yy = {1,2,2,1,-1,-2,-2,-1};
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		n = in.nextInt();
		m = in.nextInt();
		a = in.nextInt();
		b = in.nextInt();
		for( int i=1; i<=n; i++ ) {
			for( int j=1; j<=m; j++ ) {
				vis = new int[401][401];
				ans = Integer.MAX_VALUE;
				endx = i;
				endy = j;
//				System.out.println(endx+" "+endy);
				dfs(a, b, 0);
				if( ans == Integer.MAX_VALUE )
					ans = -1;
				horse[i][j] = ans;
			}
		}
		for( int i=1; i<=n; i++ ) {
			for( int j=1; j<=m; j++ ) {//左对齐,“%-5d”
				System.out.print(String.format("%-5d", horse[i][j]));
			}
			System.out.println();
		}
	}
	public static void dfs( int o, int p, int num ) {
		if( num >= ans )//如果比ans大就截了
			return;
		if( o == endx && p == endy ) {
			ans = Math.min(num, ans);//获取每次的最小值
			return;
		}
		for( int i=0; i<8; i++ ) {
			int x = o + xx[i];
			int y = p + yy[i];
			if( x>0 && x<=n && y>0 && y<=m && vis[x][y] == 0 ) {
				vis[x][y] = 1;
				dfs(x, y, num+1);
				vis[x][y] = 0;//回溯
			}
		}
	}
}
下面是AC代码,BFS
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		int n, m, starx, stary;
		int[][] horse = new int[401][401];//只要一个存数数组就行,开一个boolean数组标记也可
		int[] xx = {-2,-1,1,2,2,1,-1,-2};
		int[] yy = {1,2,2,1,-1,-2,-2,-1};
		Queue<Horse> queue = new LinkedList<Horse>();
		n = in.nextInt();
		m = in.nextInt();
		starx = in.nextInt();
		stary = in.nextInt();
		for( int i=1; i<=n; i++ ) {//初始化
			for( int j=1; j<=m; j++ ) {
				horse[i][j] = -1;
			}
		}
		horse[starx][stary] = 0;
		Horse h = new Horse(starx, stary, 0);
		queue.offer(h);
		while( !queue.isEmpty() ) {
			for( int i=0; i<8; i++ ) {//将每次能走的地方标上步数,直到全走完出队
				int ox = queue.peek().x + xx[i];
				int oy = queue.peek().y + yy[i];
				if( ox>=1 && ox<=n && oy>=1 && oy<=m && horse[ox][oy] == -1 ) {
					h = new Horse(ox, oy, queue.peek().sum+1);
					queue.offer(h);
					horse[ox][oy] = queue.peek().sum+1;
				}
			}
			queue.poll();
		}
		for( int i=1; i<=n; i++ ) {
			for( int j=1; j<=m; j++ ) {
				out.print(String.format("%-5d", horse[i][j]));
			}
			out.println();
		}
		out.flush();
	}
}
class Horse {
	int x, y, sum;
	Horse(int x, int y, int sum) {
		this.x = x;
		this.y = y;
		this.sum = sum;
	}
}

落谷题目连接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个有梦有戏的人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值