m个人拉m盏灯后求灯的状态问题

news2024/9/21 19:43:29

之前看过一道题:有m盏灯,编号分别为1,2,3,...,m,每拉一次灯的开关,灯的亮灭状态就发生一次变化。这m盏灯初始状态都是亮着的,有m个人去拉灯,第1个人把所有的灯都拉一次,第2个人把编号是2的倍数的灯拉都拉一次,第3个人把编号是3的倍数的灯都拉一次,...,第m个人把编号是m的灯都拉一次。问:最终哪些编号的灯是灭的?

以下是解决这种问题的几种方法。

目录

一、人工按步骤操作

二、编程求解方法

1、编程方法一:最基本编程求解思路

2、编程方法二:数理分析+枚举法

3、编程方法三:求m中最大平方根法


一、人工按步骤操作

如果m的数值比较小,可以用手动的方法一个个去试一下,也是可以做出来的,如下表所示。

灯1灯2灯3灯4灯5灯6灯7灯8灯9灯10
初始
拉1次
拉2次
拉3次
拉4次
拉5次
拉6次
拉7次
拉8次
拉9次
拉10次

但这种方法效率太低了,而且容易出错,如果m值很大,用这种手动的方法就更不可行了。

二、编程求解方法

1、编程方法一:最基本编程求解思路

可以用编程的方法来解决,这个问题如果用c++语言编程的思路如下:

第一步:声明一个整形变量m,由键盘输入m的具体值。

第二步:声明一个有m+1个元素的布尔型数组,其中脚标为1到m的元素用于存储m盏灯的亮灭状态,亮为1,灭为0。

第三步:用for循环求解当所有人都拉过一次灯后,灯的状态。这一步是关键,灯的序号用i表示,人的序号用j表示,从i=1开始到m结束,循环求解j=1开始到m结束,i是否是j的倍数,如果是则序号为i的灯状态翻转一次。

第四部:把状态为灭的灯的序号输出。

具体代码如下:

#include <iostream>
using namespace std;
 
int main()
{
    int m;    //声明m盏灯
    cin>>m;    //键盘输入m的具体数值    
    bool lamp_status[m+1];    //声明存储灯状态的布尔型变量数组,1为亮,0为灭

    for(int i=1;i<=m;i++)    //循环求解i盏灯的状态
        {
            lamp_status[i]=1;    //灯的初始状态为亮
            for(int j=1;j<=m;j++)    //循环求解第j个人拉灯之后,灯的状态变化
                {
                    if(i%j==0)        //如果i是j的倍数,则灯的状态进行翻转
                    lamp_status[i]=!lamp_status[i];
                }
                
            if(lamp_status[i]==0)     //如果灯的状态为灭则输出灯的序号
                {
                    cout<<i<<endl;
                }
        } 
    return 0;
}

运行程序,当m=10时,结果如下:

1
4
9

当m=100时,结果如下:

1
4
9
16
25
36
49
64
81
100

运算结果与题目给出的答案是一致的,编程求解的算法成功。

2、编程方法二:数理分析+枚举法

但本文目的不仅在此。

通过观察编程方法一运行的结果发现,灯状态为灭的序号都是完全平方数!为了排除巧合,把m的值再加大到1000,10000,得到的所有结果仍然是完全平方数。也就是说,这不是偶然的现象,而是一个必然的规律。

那么这个规律是什么呢?我们从数学角度来分析一下。

用i来表示从1到m的某盏灯的编号,j表示从1到m的某个拉灯的顺序号。

第i盏灯的最终亮灭状态是由灯的状态翻转次数决定的,当翻转次数是奇数次,那么灯的状态与初始状态相反,为灭;当翻转次数为偶数次,灯的状态与初始状态相同,为亮。

第j个人拉灯时,当i是j的倍数,或者说j是i的因数时,第i盏灯状态才发生翻转。而j的最大值和i的最大值都为m,那么第i盏灯翻转的次数等于i的因数的个数。

所以求解第i盏灯的状态问题,就转化为求解i这个自然数含有因数的个数是奇数还是偶数的问题。那么一个自然数,它的因数的个数有什么规律呢?这个就跟这个自然数是不是完全平方数有关,我们知道一个自然数总可以表示成另外两个自然数相乘的形式,这两个自然数就是它的因数。

比如:1=1×1,2=1×2;4=1×4=2×2;5=1×5;6=1×6=2×3,7=1×7,8=1×8=2×4,12=1×12=2×6=3×4,36=1×36=2×18=3×12=4×9=6×6...。

通过观察发现,一个自然数的因数都是成对出现的,当存在某对因数相等的时候,这个自然数就是完全平方数,也就是完全平方数的因数的个数是奇数而非完全平方数,不存在某对因数相等的情况,所以因数的个数为偶数

至此,判断第i盏灯状态是否是亮灭的时候,就转化为看i是否为完全平方数的问题了,当i为完全平方数,其因数个数为奇数个,第i盏灯状态与初始状态相反,为灭;当i不是完全平方数时,其因数个数为偶数个,第i盏灯状态与初始状态相同,为亮。所以,这个问题实际就是求解从1到m的自然数中一共有哪几个完全平方数。

这个问题怎么用c++语言来求呢?

思路如下:可以从1到m,一个一个判断i是否是完全平方数,如果是就枚举出来。判断的方法是先求i的平方根,然后取整,再把取整后的平方根进行求平方运算。如果i是完全平方数,其平方根是整数,取整后不变,对取整后的平方根进行平方运算,结果和i相等。如果i不为完全平方数,那么其平方根不为整数,取整后再进行平方运算,结果会小于i。

根据以上思路,程序代码如下:

#include <iostream>
#include <math.h>
using namespace std;
 
int main()
{
    int m;    //声明m盏灯
    cin>>m;    //键盘输入m的具体数值
    for(int i=1;i<=m;i++)    //循环求解i盏灯的状态
        {
            int squarRoot=sqrt(i);    //求i的平方根并取整
            if(squarRoot*squarRoot==i)    //如果取整后的平方根的平方与i相等,说明i的平方根为整数,i是完全平方数
            cout<<i<<endl;
        } 
    return 0;
}

运行的结果和编程方法一的结果是一样的。

3、编程方法三:求m中最大平方根法

通过观察发现,自然数m以内的完全平方数,虽然不是连续的自然数,但这些完全平方数的平方根是连续的自然数,如下表所示。

完全平方数149162536496481100...
对应平方根12345678910...

所以,当我们知道m的具体值时,m的平方根的整数部分为m_{0},那么m_{0}就是m以内最大完全平方数对应的那个最大平方根,{1,2,...,m_{0}}就是所有的完全平方数对应的平方根,知道了这些平方根,那么再反过来求出完全平方数的集合为{1^{2},2^{2},3^{2},...,m_{0}^{2}}。

根据以上思路的编程代码如下:

#include <iostream>
#include <math.h>
using namespace std;
 
int main()
{
    int m;    //声明m盏灯
    cin>>m;    //键盘输入m的具体数值
    int MaxsquarRoot=sqrt(m);       //求平方数为m的最大整数平方根,那么小于等于这个最大整数平方根的所有自然数的平方都是小于m的完全平方数。
    for(int i=1;i<=MaxsquarRoot;i++)    //循环求解i盏灯的状态
        {
            cout<<i*i<<endl;
        } 
    return 0;
}

对比三种编程方法,从时间复杂度上来说,方法一的时间复杂度为o(n^2),方法二为o(n),而方法三为o(1),方法三完胜!方法三不但时间复杂度低,而且适合人工求解,真是个好方法。

(全文结束)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1934709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Qt】之【Bug】error:C1083 无法打开包括文件

背景 a.cpp引用b.h正常&#xff0c;但是a.h引用b.h就报 “无法打开包括文件”的错误 分析 查看“编译输出”&#xff0c;显示不是a.h引起的错误&#xff0c;而是C插件&#xff0c; 查看后发现&#xff0c;C插件引用了a所在插件pro&#xff0c;但是没有引用a依赖的b所在的插件…

AI 模型本地推理 - YYPOLOE - Python - Windows - GPU - 吸烟检测(目标检测)- 有配套资源直接上手实现

Python 运行 - GPU 推理 - windows 环境准备python 代码 环境准备 FastDeploy预编译库下载 conda config --add channels conda-forge && conda install cudatoolkit11.2 cudnn8.2 pip install fastdeploy_gpu_python-0.0.0-cp38-cp38-win_amd64.whlpython 代码 impo…

[Doris]阿里云搭建Doris,测试环境1FE 1BE

首先&#xff1a;阿里云的国内服务器千万不要用容器搭建&#xff0c;或者自己Dockfile构建镜像。两种方式都不得行&#xff0c;压根拉不到github的镜像&#xff0c;开了镜像加速器也拉不到&#xff0c;不要折腾了&#xff0c;极其愚蠢。 背景&#xff1a;现在测试环境&#xff…

排序算法(4)之快速排序(2)

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 排序算法(4)之快速排序(2) 收录于专栏【数据结构初阶】 本专栏旨在分享学习数据结构学习的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目…

Pytorch学习笔记day3——用神经网络学习一组函数

好的&#xff0c;我们开始吧。首先第一个问题&#xff0c;神经网络的本质是什么&#xff1f;是古典主义的人类的神经元吗&#xff1f;绝对不是&#xff0c;他只是一个优化函数 y f θ ( x ) y f_{\theta}(x) yfθ​(x) 这和小学学到的线性函数拟合并无本质区别。只是其中参数…

使用IDEA编写lua脚本并运行

下载lua https://github.com/rjpcomputing/luaforwindows/releases 是否创建桌面快捷方式&#xff1a;我们的目标是使用IDEA编写lua脚本&#xff0c;所以不需要勾选。后面需要的话&#xff0c;可以到安装目录下手动创建快捷方式 环境变量自动配置 安装后会自动配置好环境变量…

Net8 Spire最新版去水印,去页数限制,转word/pptx/ofd等

新建控制台程序&#xff0c;添加Spire.pdf&#xff0c;最新版本为2024年7月17日 try {Spire.Pdf.PdfDocument pdf new Spire.Pdf.PdfDocument();pdf.LoadFromFile("test.pdf");pdf.SaveToFile("newpdf.pdf");pdf.SaveToFile("newppx.pptx", Spi…

20分钟迁移完阿里云ECS跨区域迁移,用老操作系统作为新服务操作系统

由于特殊原因或者数据备份需要迁移ecs服务器 跨区域复制 镜像复制 由于特殊原因或者数据备份需要迁移ecs服务器 1.老服务快照 选择ecs实例&#xff0c;点开实例 进入云盘 https://ecs.console.aliyun.com/disk 在云盘上点击建立快照 https://oss.console.aliyun.com/bu…

PyTorch 深度学习实践-循环神经网络基础篇

视频指路 参考博客笔记 参考笔记二 文章目录 上课笔记基于RNNCell实现总代码 基于RNN实现总代码 含嵌入层的RNN网络嵌入层的作用含嵌入层的RNN网络架构总代码 其他RNN扩展基本注意力机制自注意力机制&#xff08;Self-Attention&#xff09;自注意力计算多头注意力机制&#xf…

纯前端小游戏,4096小游戏,有音效,Html5,可学习使用

// 游戏开始运行create: function(){this.fieldArray [];this.fieldGroup this.add.group();this.score 0;//4096 增加得分this.bestScore localStorage.getItem(gameOptions.localStorageName) null ? 0 : localStorage.getItem(gameOptions.localStorageName);for(var …

vscode通过ssh链接远程服务器上的docker

目录 1 编译docker image1.1 编译镜像1.2 启动镜像 2 在docker container中启动ssh服务2.1 确认是否安装ssh server2.2 修改配置文件2.3 启动ssh服务 3 生成ssh key4 添加ssh公钥到docker container中5 vscode安装插件Remote - SSH6 在vscode中配置 1 编译docker image 一般来…

uni-app开发日志:unicloud使用时遇到的问题解决汇总(不断补充)

插件安装后提示与原数据库表冲突&#xff08;2024.7.18&#xff09; 安装uni-admin后再安装uni-cms&#xff0c;在uni-admin中添加好菜单&#xff0c;结果提示该错误 回到hbuilder中uniCloud/database中找到冲突的部分 比较一下&#xff0c;选中老的删除 opendb-news-articl…

第122天:内网安全-域信息收集应用网络凭据CS 插件AdfindBloodHound

目录 前置知识 背景和思路 判断是否在域内 案例一&#xff1a;架构信息类收集-网络&用户&域控等 案例二&#xff1a;自动化工具探针-插件&Adfind&BloodHound Adfind(域信息收集工具) ​BloodHound&#xff08;自动化域渗透工具&#xff09; 前置知识 本…

【Git标签管理】理解标签 | 创建标签 | 查看标签 | 删除标签 | 推送标签

目录 1.理解标签 2.创建标签 3.查看标签 4.删除本地仓库的标签 5.推送标签 6.删除远程仓库的标签 1.理解标签 Git提供一个打标签的功能tag&#xff0c;对某一次事务/提交的表示&#xff08;作用/意义&#xff09;。标签 tag &#xff0c;可以简单的理解为是对某次 comm…

【Git】(基础篇四)—— GitHub使用

GitHub使用 经过上一篇的文章&#xff0c;相信大家已经对git的基本操作熟悉了&#xff0c;但哪些使用git的方法只是在本地仓库进行&#xff0c;本文介绍如何使用git和远程仓库进行连接使用。 Github和Gitee 主要用到的两个远程仓库在线平台是github和gitee GitHub GitHub …

Postman导出excel文件

0 写在前面 在我们后端写接口的时候&#xff0c;前端页面还没有出来&#xff0c;我们就得先接口测试&#xff0c;在此记录下如何使用postman测试导出excel接口。 如果不会使用接口传参可以看我这篇博客如何使用Postman 1 方法一 2 方法二 3 写在末尾 虽然在代码中写入文件名…

node解析Excel中的考试题并实现在线做题功能

1、背景 最近公司安排业务技能考试&#xff0c;下发excel文件的题库&#xff0c;在excel里查看并不是很方便&#xff0c;就想着像学习驾考题目一样&#xff0c;一边看一边做&#xff0c;做完之后可以查看正确答案。 2、开始分析需求 题目格式如下图 需求比较简单&#xff0c;…

JCR一区级 | Matlab实现PSO-Transformer-LSTM多变量回归预测

JCR一区级 | Matlab实现PSO-Transformer-LSTM多变量回归预测 目录 JCR一区级 | Matlab实现PSO-Transformer-LSTM多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现PSO-Transformer-LSTM多变量回归预测&#xff0c;粒子群优化Transformer结合LST…

浅聊 Three.js 屏幕空间反射SSR-SSRShader

浅聊 Three.js 屏幕空间反射SSR(2)-SSRShader 前置基础 渲染管线中的相机和屏幕示意图 -Z (相机朝向的方向)||| -------------- <- 屏幕/投影平面| | || | || | (f) | <- 焦距| | ||…

新文件覆盖旧文件还能复原吗?八大excel文档修复软件免费

新文件覆盖旧文件还能复原吗&#xff1f;文件操作失误&#xff0c;尤其是新文件意外覆盖旧文件的情况时有发生&#xff0c;面对文件被覆盖的情况&#xff0c;我们不仅需要冷静应对&#xff0c;更需要掌握一系列有效的恢复策略。本文将深入探讨八种免费方法&#xff0c;旨在帮助…