题目
小Q正在给一条长度为n的道路设计路灯安置方案。为了让问题更简单,小Q把道路视为
n个方格,需要照亮的地方用 '.' 表示, 不需要照亮的格子用 'X' 表示。小Q现在要在道路上设置一些路灯, 只能在'.'区域安装路灯
对于安置在 pos位置的路灯, 这盏路灯可以照亮 pos-1,pos,pos+1这三个位置。但是有个限制,不需要照亮的格子上面不能放置路灯。
小Q希望能安置尽量少的路灯照亮所有 '.' 区域, 希望你能帮他计算一下最少需要多少盏路灯。
输入描述:
第一行一个正整数n 第二行为一个长度为n的字符串,仅由 '.' 和 'X' 这两种字符组成。
输出描述:
最少需要放置的路灯数量
示例1
输入
5 .X.X.
输出
3
说明
由于不需要照亮的格子上面不能放置路灯,所以必须在1,3,5这三个位置放置路灯
示例2
输入
5 .....
输出
2
说明
在2,4这两个位置放置路灯即可。
思路分析:
- 定义一个递归函数。lookForward(pos)表示,从i到道路尽头至少需要安置多少盏路灯,
- 当pos为道路尽头时,返回0或者1(取决于道路尽头是'.'还是'X')return 0/1
- 当pos此时为'X'时,此地不需要放,所以( 即跳过此pos)返回l(pos+1)
- return lookForward(pos+1)
- 当pos此时为' .'时,需要向后看一个pos+1;
- 若pos+1为'X', 则在pos处放置一盏灯,pos+1不用管(X),然后在调用l(pos+2), return 1+lookForward(pos+2)
- 若pos+1为' .',则在pos+1处放置一盏灯(既可以照亮pos,又可以照亮pos+1/pos+2),所以pos+1,pos+2都被照亮了不用管,调用l(pos+3), return 1+lookForward(pos+3)
易错点:
在思路分析中的第2,3种情况中,会返回i+1,i+2,i+3等,可能会导致越界。
所以在判断函数递归结束条件时,需要判断如果pos>=str.length(),需要返回0,(超过道路尽头了,当然不需要再放置路灯了)
难点:
- 一开始时,我的想法时用字符数组char[], 但在输入时String更具有普遍性,所以选择了String
- 如何在String中选取对应索引的字符呢,可以用str.chatAt(pos);
- 如何得到字符串的长度,str.length(), 注意数组的长度时属性,字符串的长度是方法(因为字符串是引用类型)
代码展示:
import java.util.Scanner;
public class Main{
public static int lookForward(int i,String str){
if(i > str.length()-1){
return 0;
}
if(i == str.length()-1){
if(str.charAt(i) == 'X'){
return 0;
}else{
return 1;
}
}else{
if(str.charAt(i) == 'X'){//此地是墙,所以不用管,看后一个的lookForward
return lookForward(i+1,str);
}else{
if(str.charAt(i+1) == 'X'){//向前看一个,如果是墙,则在此地放一个加上后两个的lookForward
return 1+lookForward(i+2,str);
}else{//向前看一个,如果是地,则在下一个的地上放一个加上后三个的lookForward
return 1+lookForward(i+3,str);
}
}
}
}
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int n = in.nextInt();
String str;
str = in.next();
System.out.println(lookForward(0,str));
}
}