zoukankan      html  css  js  c++  java
  • 【题目】开灯关灯问题

    题目

    有n(n>0)盏灯,编号为1~n,在桌子上排成一排。开始都是熄灭状态。

    第1趟,按下编号为1 的倍数的 灯的开关。(第一趟后所有的灯都亮了)

    第2趟,按下编号为2 的倍数的 灯的开关。

    ....

    第 i 趟,按下编号为i 的倍数的 灯的开关。

    一直到第n趟,结束。

    :n趟过后,哪些灯亮着,哪些熄灭,有多少亮着?

    根据问题,很直接的写出代码。

    #include<iostream>
    #include<cassert>
    #include<cstring>
    
    using namespace std;
    
    void onoff(size_t n)
    {
        int*door = new int[n+1];
        memset(door, 0, sizeof(int)  * (n + 1));
    
        for (size_t i = 1; i <=n ; i++)       // 走n趟
        {
            for (size_t k = i; k <=n; k+=i)  //比 i 小的数都不用考虑,因为他们不是 i 的倍数、。
            {
    
                if (k%i == 0)                //如果门k 是 i的整数倍,则改变他的状态
                    door[k] = !door[k];
            }
    
        }
    
    
        for (size_t  i = 1; i <=n; i++)
        {
            cout << door[i] << ' ';
        }
    
        delete[] door;
    
    }
    
    
    
    int main()
    {
        for (size_t i = 1; i <= 36; i++)
        {
            cout << "n=" << i<<'	'; 
            onoff(i);
            cout << endl;
        }
        
        
        return 0;
    }

    运行结果

    n=1     1
    n=2     1 0
    n=3     1 0 0
    n=4     1 0 0 1
    n=5     1 0 0 1 0
    n=6     1 0 0 1 0 0
    n=7     1 0 0 1 0 0 0
    n=8     1 0 0 1 0 0 0 0
    n=9     1 0 0 1 0 0 0 0 1
    n=10    1 0 0 1 0 0 0 0 1 0
    n=11    1 0 0 1 0 0 0 0 1 0 0
    n=12    1 0 0 1 0 0 0 0 1 0 0 0
    n=13    1 0 0 1 0 0 0 0 1 0 0 0 0
    n=14    1 0 0 1 0 0 0 0 1 0 0 0 0 0
    n=15    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0
    n=16    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1
    n=17    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0
    n=18    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0
    n=19    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0
    n=20    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0
    n=21    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0
    n=22    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0
    n=23    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0
    n=24    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
    n=25    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1
    n=26    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0
    n=27    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0
    n=28    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0
    n=29    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0
    n=30    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0
    n=31    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
    n=32    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
    n=33    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
    n=34    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
    n=35    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
    n=36    1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1

    分析总结

    仔细分析后,发现,被按偶数次的灯,最后是熄灭的,而被按奇数次的灯,最后是亮的。而且从运行结果中可以看出规律:最后亮的灯,其编号都是完全平方数。第1盏,第4盏,第9盏...

    举几个例子。

    7 = 1 x 7             编号为7,在第1 趟和第 7 趟被按下。


    30 = 1 x 30        编号为30,在1,30 ,2, 15 , 3 , 10 趟都会被按下。
        = 2 x 15
        = 3 x 10

    1 = 1 x 1             编号为1, 在第 1趟被按下

    4 = 1 x 4            编号为4 , 在第1  4  2  趟被按下

       = 2 x 2

    可以发现,编号是完全平方数,就会被按奇数次。否则会按下偶数次。因此,这个题目转而变为判断哪些数是完全平方数了。

    即:编号为完全平方数的灯,最后是亮的,否则就是熄灭的。

    判断一个数是否是完全平方数(不考虑负数)

    bool isPerfectSquare(unsigned int n)
    {
        unsigned int low = (unsigned int)sqrt(n);
    
        return (low*low == n) || ((low + 1)*(low + 1) == n);
    
    
        /*  之所以不直接用 low*low==n判断,是因为浮点数的不精确存储。比如  sqrt(25)在某些时候【可能】会返回4.999999 ,取整后变为4了。  
            因此,以防意外,我们需要再往上增1判断。 || 是满足短路求值的,因此性能不会损失
        
        */
    
    
    }
  • 相关阅读:
    DataPager 分页样式(css)
    Mysql日志详解
    Oracle 优化器
    [oracle]对象统计数据
    [oracle] analyze 和dbms_stats 的区别
    增加SAP HEAP大小
    Problems with SYSDBA/SYSOPER/INTERNAL connect
    Physical Standby Switchover_status Showing Not Allowed
    REHL8 oracle 19C RAC安装中的坑
    REHL8 oracle 19C RAC安装四(数据库创建)
  • 原文地址:https://www.cnblogs.com/lulipro/p/6685859.html
Copyright © 2011-2022 走看看