【问题描述】
你们全家正在一条路上开车旅行。你的父亲给你一张地图,途上标注了什么地方车子需要转弯。比如,
String[] map = {".........R....",
"..............",
"...L.....R....",
"..............",
"...L.....B...."}
'.'代表直行,'R'代表右转,'L'代表左转,'B'代表回转。在你们离开地图或者在图中无限循环之前,需要一直遵循该图的指引。假设你们开始是在图的左上角的顶点向右侧行驶,按照上面的地图你们的路程将会是:
>>>>>>>>>v....
..............
.........v....
..............
...v<<<<<<....
..............
...v..........
..............
...>>>>>><....
...v<<<<<<....
转动的方向是和你们正在前进的方向相关的。你的家人想要尽可能多的拍摄沿途的风景照片,换句话说,就是想要游览地图上尽可能多的地方。在上例中,你们的车经过了地图中的这些点:
xxxxxxxxxx....
.........x....
...xxxxxxx....
...x..........
...xxxxxxx....
'X'的总数量是26。现在你的任务是找到最佳的出发点和初始方向,使得可以经过图中尽可能多的位置(重复算一次),返回所经过的位置的数量。在上例中,旅行的路线是能达到最多位置的方式之一,因此你的方法返回26。如果在你进入地图的点上有转向标志那么该标志立刻生效。例如,map = {"R...B"},如果你们最开始在左上角点方向向右,那么你们的路线将是v....,如果你们开始于最右面的点并且方向是向右,那么你们的路线是^<<<<,因此你的方法应该返回5。注意,可能会出现无限循环的情况(永远出不了地图),但是无论如何总是需要返回你们能经过位置的个数。
定义:
类 RoadTrip
方法 public int howMany(String[] map)
约束:
1、你选择的开始点一定在该图上,并且方向是上下左右之一
2、地图一定包括1至30个元素
3、每个元素的长度是1至30
4、地图的每个元素包含相同的长度
5、地图中仅包含"BRL."该四种字符
测试用例:
1、
{".........R....",
"..............",
"...L.....R....",
"..............",
"...L.....B...."}
Returns: 26
2、
{".........R.....R.......",
".......................",
".........B.............",
".......................",
".......................",
"..B......R.....R......B",
".......................",
".......................",
".......................",
".........B.....B......."}
Returns: 60
3、
{"......................R",
"R....................R.",
".R..................R..",
"..R................R...",
"...R..............R....",
"....R.............R....",
"...R...............R...",
"..R.................R..",
".R...................R.",
"R.....................R"}
Returns: 230
4、
{".B.....B"}
Returns: 7
【算法思想】
遍历使用该图中每一个点(作为起始点)和每一个方向,计算所遍经位置的数量,最后取最大值。
注:判断路径陷入死循环的方法,记录2个计数器,一个是不重复的位置计数sum,一个是所经历的位置计数count,如果如果count=2*sum那么就是循环。
你们全家正在一条路上开车旅行。你的父亲给你一张地图,途上标注了什么地方车子需要转弯。比如,
String[] map = {".........R....",
"..............",
"...L.....R....",
"..............",
"...L.....B...."}
'.'代表直行,'R'代表右转,'L'代表左转,'B'代表回转。在你们离开地图或者在图中无限循环之前,需要一直遵循该图的指引。假设你们开始是在图的左上角的顶点向右侧行驶,按照上面的地图你们的路程将会是:
>>>>>>>>>v....
..............
.........v....
..............
...v<<<<<<....
..............
...v..........
..............
...>>>>>><....
...v<<<<<<....
转动的方向是和你们正在前进的方向相关的。你的家人想要尽可能多的拍摄沿途的风景照片,换句话说,就是想要游览地图上尽可能多的地方。在上例中,你们的车经过了地图中的这些点:
xxxxxxxxxx....
.........x....
...xxxxxxx....
...x..........
...xxxxxxx....
'X'的总数量是26。现在你的任务是找到最佳的出发点和初始方向,使得可以经过图中尽可能多的位置(重复算一次),返回所经过的位置的数量。在上例中,旅行的路线是能达到最多位置的方式之一,因此你的方法返回26。如果在你进入地图的点上有转向标志那么该标志立刻生效。例如,map = {"R...B"},如果你们最开始在左上角点方向向右,那么你们的路线将是v....,如果你们开始于最右面的点并且方向是向右,那么你们的路线是^<<<<,因此你的方法应该返回5。注意,可能会出现无限循环的情况(永远出不了地图),但是无论如何总是需要返回你们能经过位置的个数。
定义:
类 RoadTrip
方法 public int howMany(String[] map)
约束:
1、你选择的开始点一定在该图上,并且方向是上下左右之一
2、地图一定包括1至30个元素
3、每个元素的长度是1至30
4、地图的每个元素包含相同的长度
5、地图中仅包含"BRL."该四种字符
测试用例:
1、
{".........R....",
"..............",
"...L.....R....",
"..............",
"...L.....B...."}
Returns: 26
2、
{".........R.....R.......",
".......................",
".........B.............",
".......................",
".......................",
"..B......R.....R......B",
".......................",
".......................",
".......................",
".........B.....B......."}
Returns: 60
3、
{"......................R",
"R....................R.",
".R..................R..",
"..R................R...",
"...R..............R....",
"....R.............R....",
"...R...............R...",
"..R.................R..",
".R...................R.",
"R.....................R"}
Returns: 230
4、
{".B.....B"}
Returns: 7
- public class RoadTrip {
- private char[][] maps;
- public int howMany(String[] map) {
- int max = 0, tmp = 0;
- maps = new char[map.length][map[0].length()];
- for (int i = 0; i < maps.length; i++)
- for (int k = 0; k < maps[0].length; k++)
- maps[i][k] = map[i].charAt(k);
- for (int i = 0; i < maps.length; i++)
- for (int k = 0; k < maps[0].length; k++)
- for (int d = 0; d < 4; d++) {
- tmp = getSpotCount(i, k, d);
- max = tmp > max ? tmp : max;
- }
- return max;
- }
- // 0--right 1--down 2--left 3--up
- private int getSpotCount(int x, int y, int direct) {
- int[][] past = new int[maps.length][maps[0].length];
- int sum = 0, count = 0;
- while (x >= 0 && x < maps.length && y >= 0 && y < maps[0].length) {
- if (past[x][y] == 0) {
- sum++;
- past[x][y] = 1;
- }
- count++;
- if (maps[x][y] != '.')
- direct = getDirect(direct, maps[x][y]);
- if (direct == 0)
- y++;
- else if (direct == 1)
- x++;
- else if (direct == 2)
- y--;
- else if (direct == 3)
- x--;
- if (count == 2 * sum)
- break;
- }
- return sum;
- }
- private int getDirect(int srcDirect, char turn) {
- if (turn == 'R')
- return srcDirect + 1 > 3 ? srcDirect + 1 - 4 : srcDirect + 1;
- if (turn == 'L')
- return srcDirect + 3 > 3 ? srcDirect + 3 - 4 : srcDirect + 3;
- if (turn == 'B')
- return srcDirect + 2 > 3 ? srcDirect + 2 - 4 : srcDirect + 2;
- return -1;
- }
- }
遍历使用该图中每一个点(作为起始点)和每一个方向,计算所遍经位置的数量,最后取最大值。
注:判断路径陷入死循环的方法,记录2个计数器,一个是不重复的位置计数sum,一个是所经历的位置计数count,如果如果count=2*sum那么就是循环。