Java 第十一届 蓝桥杯 省模拟赛 梅花桩

小明每天都要练功,练功中的重要一项是梅花桩。
  小明练功的梅花桩排列成 n 行 m 列,相邻两行的距离为 1,相邻两列的距离也为 1。
  小明站在第 1 行第 1 列上,他要走到第 n 行第 m 列上。小明已经练了一段时间,他现在可以一步移动不超过 d 的距离(直线距离)。
  小明想知道,在不掉下梅花桩的情况下,自己最少要多少步可以移动到目标。
输入格式
  输入的第一行包含两个整数 n, m,分别表示梅花桩的行数和列数。
  第二行包含一个实数 d(最多包含一位小数),表示小明一步可以移动的距离。
输出格式
  输出一个整数,表示小明最少多少步可以到达目标。
样例输入
3 4
1.5
样例输出
3

10评测用例规模与约定
  对于 30% 的评测用例,2 <= n, m <= 20,1 <= d <= 20。
  对于 60% 的评测用例,2 <= n, m <= 100,1 <= d <= 100。
  对于所有评测用例,2 <= n, m <= 1000,1 <= d <= 100。

PS:
这里的搜索肯定是找半径搜索,肯定是半径搜索的最右下面的,
下面那个图,看一下,我的y2是最靠下的位置,x2++,如果超出了半径范围,
那么y2就往上走,x2++的范围继续搜索,如果没有超过半径范围,x2++就继续向右面找
然后在超过半径,就y2–往上走,知道y2<y1,
因为他是右下走,所以你只需要考虑右下方向的路径
不好意思,实在是不清楚怎么把他转过来
在这里插入图片描述

在这里插入图片描述

package 蓝桥杯省模拟赛_高职组;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class 梅花桩 {
    public static void main(String[] args) {
        List<Integer> list_y = new ArrayList<Integer>();
        List<Integer> list_x = new ArrayList<Integer>();
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        double d = sc.nextDouble();
        sc.close();
        int[][] map = new int[n+1][m+1];
        list_x.add(1);
        list_y.add(1);
        while (list_x.size()!=0){
            int x1 =list_x.remove(0);
            int y1=list_y.remove(0);
            int x2=x1;
            int y2=y1+(int)d;
            if((n-x1)*(n-x1) + (m-y1)*(m-y1) <= d*d)
            {
                map[n][m] = map[x1][y1] + 1;
                break;
            }
            while (x2 <= n && y2 >= y1 && y2 <= m){
                if((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) <= d * d && map[x2][y2] == 0)
                {
                    list_x.add(x2);
                    list_y.add(y2);
                    map[x2][y2] = map[x1][y1] + 1;
                    x2 ++;
                }
                else y2 --;
            }
        }
        System.out.println(map[n][m]);
    }
}

原文地址:https://www.cnblogs.com/a1439775520/p/13074754.html