LeetCode 319. 灯泡开关

题目:
  初始时有 n 个灯泡处于关闭状态。第一轮,你将会打开所有灯泡。接下来的第二轮,你将会每两个灯泡关闭第二个。
  第三轮,你每三个灯泡就切换第三个灯泡的开关(即,打开变关闭,关闭变打开)。第 i 轮,你每 i 个灯泡就切换第 i 个灯泡的开关。直到第 n 轮,你只需要切换最后一个灯泡的开关。
  找出并返回 n 轮后有多少个亮着的灯泡。

解法:
  模拟算法、0-暗、1-亮,可以使用"异或",异或 1 代表改变开关、异或 0 代表未改变开关
  因此n为 6 方法如下:0 ^ 0b111111 ^ 0b010101 ^ 0b001001 ^ 0b000100 ^ 0b000010 ^ 0b000001

  易得、第i位灯泡是亮还是暗,取决于 i 这个数字对[1 ~ n]整除的个数是奇数还是偶数,转化为 i 的公约数是奇数个还是偶数个
  此时、质数只能被 1 和他本身整除、则结果一定为 0,合数则模拟线性筛计算[3 ~ n]中合数是奇数个还是偶数个
  注意0、1以及乘法溢出即可

  但是使用线性筛过程中,发现如果相同俩数乘积等于 n 的情况下,就只开关一次、否则一定开关两次变回原状态
  易得、结果其实就是[1 ~ n]^2 <= n 的个数,转换一下就是n的开方下取整
  注意需要加上 0.5 避免sqrt(3.99999)等这类浮点精度问题

代码:

    private static int solution(int n) {
        int result = (int)Math.sqrt(n + 0.5);
        return result;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值