/*
机器人的运动范围:
地上有一个m行和n列的方格。
一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。
例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。
但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
思路1:
应该是求最多能到达多少格子吧,因为选择的路径不同,可达的格子数也不同
与66题矩阵中的路径比较像,66题是试探性的去尝试一条路径,如果不能匹配字符串,则回溯;本题应该是要遍历所有路径,看哪条路径可达格子最多
剑指offer思路:不是说机器人必须沿着一路径走,只需要关注机器人可以到达的区域
两种思路的结果是一样的
*/
class MovingCount
{
static int count;
public static int movingCount(int threshold, int rows, int cols)
{
if (threshold<0||rows<=0||cols<=0)
{
return 0;
}
//记录方格是否被访问过
boolean[][] visited=new boolean[rows][cols];
//思路1
//reachable(0, 0, rows, cols, threshold,visited);
//剑指offer思路
count =reachable2(0, 0, rows, cols, threshold,visited);
return count;
}
public static int reachable(int row, int col, int rows, int cols, int threshold, boolean[][] visited)
{
if (row<rows&&col<cols)
{
//计算行坐标和列坐标的数位之和
int digitSum=0;
int digitRow=row;
int digitCol=col;
while (digitRow>0)
{
digitSum+=digitRow%10;
digitRow=digitRow/10;
}
while (digitCol>0)
{
digitSum+=digitCol%10;
digitCol=digitCol/10;
}
//若格子满足要求
if (digitSum<=threshold)
{
//更新可达格子数
count++;
//标记为已访问
visited[row][col]=true;
//若当前选定格子的上侧有格子且未被访问过
if(row-1>=0&&!visited[row-1][col])
{
//上侧格子作为下一个选择,最终会得到的最大格子数
int countUp=reachable(row-1, col, rows, cols, threshold,visited);
count=countUp;
}
if(row+1<rows&&!visited[row+1][col])
{
int countDown=reachable(row+1, col, rows, cols, threshold,visited);
if (countDown>count)
{
count=countDown;
}
}
if(col-1>=0&&!visited[row][col-1])
{
int countLeft=reachable(row, col-1, rows, cols, threshold,visited);
if (countLeft>count)
{
count=countLeft;
}
}
if(col+1<cols&&!visited[row][col+1])
{
int countRight=reachable(row, col+1, rows, cols, threshold,visited);
if (countRight>count)
{
count=countRight;
}
}
}
}
return count;
}
public static int reachable2(int row, int col, int rows, int cols, int threshold, boolean[][] visited)
{
int count2=0;
if (row>=0&&row<rows&&col>=0&&col<cols&&!visited[row][col])
{
//计算行坐标和列坐标的数位之和
int digitSum=0;
int digitRow=row;
int digitCol=col;
while (digitRow>0)
{
digitSum+=digitRow%10;
digitRow=digitRow/10;
}
while (digitCol>0)
{
digitSum+=digitCol%10;
digitCol=digitCol/10;
}
//若格子满足要求
if (digitSum<=threshold)
{
//标记为已访问
visited[row][col]=true;
//向四周扩展区搜寻可以到达的格子
count2=1+reachable2(row-1, col, rows, cols, threshold,visited)+
reachable2(row+1, col, rows, cols, threshold,visited)+
reachable2(row, col-1, rows, cols, threshold,visited)+
reachable2(row, col+1, rows, cols, threshold,visited);
}
}
return count2;
}
public static void main(String[] args)
{
System.out.println(movingCount(15,20,20));
}
}
剑指offer_机器人的运动范围
最新推荐文章于 2023-10-06 10:25:23 发布