小明每天都要练功,练功中的重要一项是梅花桩。
小明练功的梅花桩排列成 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]);
}
}