猩猩点灯scu2056的解题报告

【题目】有 k 盏灯和 k 只喜欢拉灯的猩猩,他们分别编号为 1 2 3... k,k 盏灯排成一排,每个猩猩都从这k盏灯前面走过,并且拉一下编号是他倍数的灯,比如编号为3的猩猩会拉编号为 3 6 9...的灯。开始的时候每盏灯是关着的,每拉一下灯的状态就改变一下(亮暗之间),问最后有多少盏灯是亮的。猩猩和灯的编号都是顺序的。输入格式:输入 k (k >= 1 && k <= 2,000,000),当 k 为 0 时输入结束,请不要对这种情况输出任何结果。输出格式:输出最后亮着的灯的数目。 输入样例: 5 4 0 输出样例: 2 2

【分析】阅读完题目,想到一个非常简单的模拟算法: 用一个布尔数组记录2000000盏灯的亮暗情况,规定1表示亮,0表示暗。初始时2000000盏灯都是暗的,即都是0。然后依次模拟2000000只猩猩点灯的情形,即:对于猩猩k,改变下标是k的倍数的灯的亮暗情况,1改为0,0改为1。模拟结束,我们就得到了2000000盏灯最终的亮暗情况了。因此,对于某个k,只需要统计下标小于等于k的所有亮着的灯的数目即可。

这个算法虽然简单,但是时间复杂度太高。其中,模拟猩猩点灯的过程的复杂度是O(n^2)。计算复杂度已经超过了30亿(1s可以做30亿次简单的加法),因此1s的时限肯定是会超出的。于是我们必须寻找时间效率更高的算法。 既然不是模拟的题目,显然这是一道数论的题目,因此我们从数论的角度来分析这道题目。对于某盏灯n,含有的因子(包括1和n)个数为m,即灯n被m只猩猩操作过。显然,如果m是奇数,则灯n最终是亮的;如果m是偶数,则灯n最终是暗的。

现在的问题转化成如何计算n的因子个数。我们知道整数的质因数分解是一个经典的算法,因此,可以得到整数n的质因数分解。假设n被分解成p1^a1* p2^a2(其中p1和p2是质数,a1和a2是整数),那么n的因子个数m=(a1+1)*(a2+1)。考虑上面这个表达式,由乘法运算的奇偶性质,m是奇数的必要条件是ai为偶数。

至此,我们得到一个非常重要的结论: 如果灯n最终是亮的,那么n可以表示成: n = p1^a1* p2^a2… pi^ai… ph^ah = p1^2b1 *p2^2b2… pi^2bi… ph^2bh = ( p1^b1* p2^b2… pi^bi… ph^bh )^2 其中p1,p2,pi,ph是小于等于sqrt(n)的质数,b1,b2,bi,bh是任意的整数,可以为0。 进一步可以得到: n = ( p1^b1* p2^b2…pi^bi…ph^bh )^2 = ( n' )^2 于是,我们得到一个更好的结论: 灯n最终亮着的必要条件是:n是完全平方数; 而且,( n' )^2可以取遍所有小于等于n的完全平方数。

最终的结论是: 任何一个完全平方数n表示的灯最终是亮着的,其余的灯最终都是暗的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值