java解安置路灯问题

题目

小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这两个位置放置路灯即可。

思路分析:

  1. 定义一个递归函数。lookForward(pos)表示,从i到道路尽头至少需要安置多少盏路灯,
    1. 当pos为道路尽头时,返回0或者1(取决于道路尽头是'.'还是'X')return 0/1
  2. 当pos此时为'X'时,此地不需要放,所以( 即跳过此pos)返回l(pos+1)
    1. return lookForward(pos+1)
  3. 当pos此时为' .'时,需要向后看一个pos+1;
    1. 若pos+1为'X', 则在pos处放置一盏灯,pos+1不用管(X),然后在调用l(pos+2), return 1+lookForward(pos+2)
    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,(超过道路尽头了,当然不需要再放置路灯了)

难点:

  1. 一开始时,我的想法时用字符数组char[], 但在输入时String更具有普遍性,所以选择了String
    1. 如何在String中选取对应索引的字符呢,可以用str.chatAt(pos);
    2. 如何得到字符串的长度,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));
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值