两个有意思的计算机相关的智力题

1. 亮灯问题:

   现有100盏灯,编号1到100。每盏灯都有一个开关,开始时,100盏灯全部关闭。

   做如下操作:

    <1> . 第1次,按下所有编号是1 的倍数的灯的开关;

   <2> . 第2次,按下所有编号是 2 的倍数的灯的开关;

   <3> . 第3次,按下所有编号是 3 的倍数的灯的开关;

                       ……………………

   <n> . 第n次,按下所有编号是 n 的倍数的灯的开关;

                      …………………………

<100> . 第100次,按下所有编号是 100 的倍数的灯的开关。


问: 经过上述操作后, 总有几盏灯在亮, 他们的编号分别是???



分析: 每盏灯开始都是关着的,最后亮着的那盏的肯定是开关被按下了奇数次。

         而对于每盏灯,都在什么时候灯的开关被按下呢? 

        显然有上述操作可见,该灯的编号是次数的倍数时该灯被的开关被按下。

        反过来,也就是 次数是该灯编号的约数时,该灯的开关被按下。

上述,问题转化,为求灯编号的约数的个数的问题, 

     而亮灯问题转化为灯的编号的约数的个数为奇数的问题。


看到这里,我们学计算机的同学,都禁不住的,要通过编程解决该问题,

我开始也是这样想,也是这样做的。能不能多想一步,灵机一动,不用编程,就能解决呢?

先看一下,怎样通过编程,解决该问题? 更巧妙方法,稍后介绍。(也许编程都的结果,会对你有所启发^o^).(有点像启发式思维,有木有,,,)

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    int i;
    int j;
    int count; //统计约数的个数;
    int n = 0; //统计亮灯的总数;

    printf("亮灯的编号是:");
    for(i = 1; i <= 100; ++i) {
        count = 0;
        for(j = 1; j<=i; ++j){
            if(i % j == 0) ++count;
        }

        if(count % 2) {
            printf("%d ", i);
            ++n;
        }
    }
    printf("\n所有亮着的灯的个数是:%d", n);

    return 0;
}

运算结果:

result


看到上述结果,如果你只打印亮灯的个数,也许你没有发现什么,但是亮灯的编号好像看起来有规律呀(是的有规律的)。

更巧妙的解决甚至不用动笔:

前面提到上述亮灯问题等价于求约数个数为奇数的灯的编号。

一个数的约数个数为奇数,这个数有什么特征呢?

我们知道,一个数的约数总是成对存在的。

而一个数的约数的个数为奇数,说明该数一个成对的约数等于同一个数。

即该数是一个数的平方,即该数是一个平方数。

上述问问题: 亮灯问题=》灯的编号的约数为奇数个=》该等的编号是一个平方数。

而 1到100中,平方数有 1^2 = 1, 2^2 = 4, 3^2 = 9, 4^2 = 16, 5^2 = 25,

                                             6^2 = 36, 7^2= 49, 8^2 = 64 9^2 = 81, 10^2 = 100.

故,1到100中有10个平方数 ,亮灯的编号都是这些平方数。

(该题目出自,某不知名培训机构的测试题中)


2. 余数问题:

        有这样一个三位数, 被5余4,被6除余5,被7除余6, 求这个三位数。

 

分析: <1>. 编程解决,计算机最擅长这个,穷举呗。

             <2>. 是否有更好的方法。

编程方案:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i;
    int count = 0;
    for(i = 0; i < 1000; ++i) {
        if(i % 5== 4 && i % 6 == 5 && i % 7 == 6){
            printf("%d, ", i);
            ++count;
        }
    }
    printf("\n共有%d个。", count);

    return 0;
}
计算机结果:


<2>更好方法:不妨令该数为n,有题设可知, n+1 能别 5, 6, 7 同时整除。

n+1 = 5 * 6 *7  *k; (k为整数)

且n+1 为一个三位数,则 100<=n+1 < 1000.

即 100< =210*k < 1000.

所以k= 1, 2, 3, 4, 对应的n为 209, 419, 629,839 。

如果不通过形式化的列举,往往会漏解。说的是三位数,而不是最小的三位数。

可见,形式化的重要性。将问题形式化,能够更好的解决问题。(学学抽象数学,还是哟必要的)。


(该题出现在某知名杀毒软件的笔试题中)。






              


   










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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值