一道解决的非常漂亮的算法题

这是多年以前做的一道题目,原题来自软件报或者电脑报 ,我记不清了。解决这个题目有一个关键的步骤,就是要求一个整数在一个整数三角阵中的坐标。这篇blog就是讨论这个求坐标的问题,不是讨论那个报纸上的题目。现在将题目描述如下:

三角阵如下所示:

                           1                         

                      2         3                                           

                 4         5         6   

            7        8         9        10

    11       12       13       14        15

                        ... ... ...

n     n+1    n+2             ... ...               n+k

三角阵中的每一个数字都有一个坐标对应,其中行是X轴,从右上往左下倾斜的边是Y轴。比如:2的坐标是(2,1),9的坐标是(4,3),应该很容易理解吧。下面还是从最简单的解法开始讨论。先看X轴坐标的求法。我们需要逐步的减去整数的个数,第一次减去第一行的整数个数,第二次减去第2行的整数的个数,如此重复知道给定的整数不够减而成为负数为止。这时将循环中当前使用的行数就是X轴的坐标,而不够减的数值就是Y轴的坐标。现在的问题就是怎么个减法效率才能尽可能的高,因为给定的整数可能非常的大,这里考虑理想情况,不要考虑具体一个语言的对整数溢出的限制,否则讨论算法的效率就没有意义了。

第一个方法是写一个第一项为1,公差为1的等差数列的求和函数,参数为n,返回值是前n项的和。然后开始从1循环,将返回值和给定整数比较,从而求得坐标。这个当然是最差的做法,效率几乎是最低的。如果谁在我的项目中这样写代码,那么这个月的工资会打折扣的。至少我们给出的解法应该是这样的:不能用一个求和函数来做,而是应该利用循环,从前n项的和递推出前n+1项的和,循环中应该有类似如下的递推求和代码:

          nCount = nCount + 1; nSum = nSum + nCount;

由于整个计算过程使用加减完成,并且不存在回溯的情况,虽然整数有可能会很大,但是这个解法的效率应该是不会太差的,这个非常显然。因为大O时间复杂度中最高的指数为1,效率是很高的了。所以这算是一个解法,如此写代码的话至少满足使用要求,不扣工资了。

但是这个解法有一个问题,就是太过简单。当然在很多时候简单是一个非常好的特点,但是在这里不行,简单的让人觉得简陋了。思考片刻后,我得到了又一个更好的解法。那就是在循环递推前n项的和的时候,循环递增的步长不设置为固定的1,而是可变长的,比如2的整数倍,也就是每次循环递增一倍。这样通过若干次循环后,我们可以发现给定的整数会落在前一次循环(假设此时nCount等于n)所求和,和本次循环(假设此时nCount等于2n)所求和的范围之内。即便是对于一个很大的整数,由于循环的步长是2的几何数量级的增长,所以可以很快的找到这个范围。那么找到了这个范围之后又如何呢?我们可以在脑海中假设一个数组,这个数组是这个等差数列的前n项和的数组。第一个元素是前一项的和,第二个元素是前两项的和,如此,第n个元素就是前n项的和。那么我们知道了给定整数所落在的范围,于是我们就可以使用折半查找的办法来获得X轴坐标。但是需要注意的是,这个前n项和的数组不是写死的,需要在使用的时候动态计算出第n个元素的值。显然从算法的角度看这个解法的效率远比前面那个高。我一度为这个解法得意,但是在得意的同时又感到一点遗憾,就是感觉自己不是用算法解决的效率问题,而是用编程技巧解决的问题。我隐隐的感觉似乎还有一个完美的解隐藏着。

于是继续思考,没多久我终于找到了这个完美的解,找到了一个时间复杂度与给定整数大小几乎没有关系的算法。等差数列的求和公式是这样的:S = n(n+1)/2。以前的思路都是从n求得S,然后做减法再接着判断处理,在一个灵感的帮助下,我发现可以把给定的整数看做S,通过求和公式直接求得n。这时n的整数部分就是X坐标,然后减去X坐标值所表示的前若干项的和,就可以得到Y轴的坐标。

从结果看这是最好的算法,它的最优几乎可以被证明。那么如此利用了求和公式而得到的解法能不能算是一个算法呢?当时我认为是,但是由于所用知识过于简单,我不能肯定。直到2年后我自学了一本书,名字叫组合数学,其中有一章讲到了母函数。这时我才明白,我在不自觉地情况下使用了母函数的思路解决了问题。只是这个求和公式比较简单不需要求解特征方程等等相关的东西,所以我才作了出来。至此,我的疑问得到了解答,这是一个堂堂正正的算法。

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

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

相关文章

HTTPS原理和对中间件攻击的预防

一、https/tls原理 HTTPS访问的三个阶段 第一阶段 认证站点 客户端向站点发起HTTPS请求,站点返回数字证书。客户端通过数字证书验证所访问的站点是真实的目标站点。 第二阶段 协商密钥 客户端与站点服务器协商此次会话的对称加密密钥,用于下一阶段的加…

【转】医学影像技术(中国普通高等学校本科专业)

医学影像技术专业培养适应我国社会主义现代化建设和医疗卫生事业发展需要的,德、智、体全面发展,具有基础医学、临床医学和现代医学影像必备的基本理论知识和基本技能,从事临床影像检查、诊断与治疗技术工作的高级技术应用性专门人才。 中文…

Windows CE下流驱动的动态加载

Windows CE下流驱动的动态加载 闲话少说,进入正题。查找EVC的帮助,发现函数ActivateDevice()可用来加载驱动程序。而这个函数的使用是相当简单的。我就不多说了,贴上一段帮助最能说明问题。当然,你也可以用…

HTTPS原理全面介绍【备查】

来源:https://www.cnblogs.com/haimishasha/p/11373034.html 目录 应用层协议:HTTPS 1. HTTPS定义 2. 密码学基础  3. HTTP通信问题 4. SSL/TLS协议 5. HTTP 向 HTTPS 演化的过程 5.1 对称加密 5.2 非对称加密 5.3 对称加密非对称加密 5.4 安…

【转】VTK修炼之道2_VTK体系结构1

1.OverView综述 The Visualization Toolkit consists of two basic subsystems: a compiled C class library (一个已经编译好的C类库)and an “interpreted” wrapper layer(一个用于解释的语言层) that lets you manipulate the…

WINCE6.0 DM.EXE 激活驱动失败的原因之一

前些天把WINCE6.0的开发环境建好了,今天定制了一个系统,练习了一下驱动的编写和调试。把DLL文件通过VS2005部署到开发板上,用一位大侠写的DM.EXE工具进行激活,但是发现点击激活按钮式无反应,驱动还是停在“停用”状态&…

Linux:tomcat安装/版本升级

本文适用于安装或更新tomcat版本。 1.进入tomcat目录,查看当前tomcat版本 cd /usr/local/tomcat/bin ./version.sh 2.备份原tomcat 可以拷贝原tomcat,或者直接修改原tomcat的文件夹名称作为备份。 cd /usr/local/ #方法1:创建目录&…

【转】VTK与Qt整合的示例

VTK与Qt整合的示例 VTK附带的程序示例中大多是基于控制台的,作为可视化开发工具包,VTK也可以与很多流行的GUI开发工具整合,比如MFC、Qt(题外话:Qt已经被Digia从诺基亚手中收购了,Qt现在的链接是:http://qt…

WinCE驱动调试助手V2.5

http://www.cnblogs.com/we-hjb/archive/2008/12/15/1280822.html http://blog.chinaunix.net/u1/49088/showart.php?id1279989 工欲善其事,必先利其器。做WinCE驱动的开发已有一段时间了,WinCE驱动调试助手也跟着更新了很多功能。现在只要做驱动&#…

Web应用系统中数据传递的方式汇总

本文转载自sina_blog(siangzhang) 目录 1 Socket方式 2 ftp/文件共享服务器方式 3 数据库共享数据方式 4 message方式 5 案例 随着近年来SOA(面向服务技术架构)的兴起,越来越多的应用系统开始进行分布式的设计和部署。 系统由原来单一…

【转】CT (电子计算机断层扫描)

CT(Computed Tomography),即电子计算机断层扫描,它是利用精确准直的X线束、γ射线、超声波等,与灵敏度极高的探测器一同围绕人体的某一部位作一个接一个的断面扫描,具有扫描速度快,图像清晰等特点,可用于多…

WinCE驱动的动态加载

// //TITLE: // WinCE驱动的动态加载 //AUTHOR: // norains //DATE: // Monday 22- February-2010 //Environment: // WINDOWS CE 5.0 // WinCE驱动的调试,很多人的第一感觉就是:编写好DLL文件,接着在PB中添加相关注册表信息&am…

Linux:chmod命令-修改文件或目录的权限

给新安装的tomcat/bin目录下的所有文件增加执行权限(所有用户、组) chmod -R ax /usr/local/tomcat/bin ------------------------------------------------------------------------------------------------------------------- 关于具体的chmod命令…

获取WinCE已加载驱动的信息

// //TITLE: // WinCE驱动的动态加载 //AUTHOR: // norains //DATE: // Monday 22- February-2010 //Environment: // WINDOWS CE 5.0 // WinCE驱动的调试,很多人的第一感觉就是:编写好DLL文件,接着在PB中添加相关注册表信息&am…

【转】详解冠状面_水平面_矢状面_窗宽_窗位

在接触人工智能医疗方面时,单是学习算法和代码原理还不够,需要一定的医学影像知识储备。 B超、CT、MR等都算是医疗影像,在现实生活中,从医院检查身体后拿到的胶片是处理过后的二维图像。这些医疗影像其实是三维的。 最常见的图片格…

js+ asp.Net ajax开发163邮箱效果(列表底色、多选拖动等)--checkBox多选

163邮件一个比较爽的功能就是可以通过多选邮件,拖动到左侧的文件夹列表,实现邮件归类的功能关于我对拖动分配的实现将在后文写出这里说说在CheckBox的选择中做得尝试和实现的效果、方法1。点击表格Title实现全选每行这个早有人做了,我这里借鉴一下 一块贴…

【转】医学图像中的窗宽、窗位!!

在CT等医学影像显示领域,我们经常会听到窗宽(Window Width,简写WW)、窗位(Window Level,简写WL)的概念,那么到底什么是窗宽、窗位,它们跟医学图像之间的关系又是什么? 先说一下CT值…

【Excel】使用VLOOKUP+IF实现多列条件匹配查询

excel中vlookup函数为精准匹配查找,但此函数局限于单列的精准匹配,如果需求是多列条件进行匹配,怎么通过vlookup函数实现呢? 思路:通过if函数将多列拼成一列再通过vlookup函数进行精准匹配 具体公式为VLOOKUP($F2&…

自己动手写TCC7901的GPIO驱动

// //TITLE: // 自己动手写TCC7901的GPIO驱动 //AUTHOR: // norains //DATE: // Monday 12-July-2010 //Environment: // Windows CE 5.0 TCC7901 // 如果你使用的是WinCE,然后又涉及到GPIO的操作,你会很尴尬地发现,WinCE根本就…

如何处理db2中文不显示

最近安装了db2 7.2一路装下来没有报错,但当打开db2时,不显示中文。郁闷!请教了,单位资深专家,解决方法如下:SQLLIB\java\java12\jdk\jre\lib目录下font.properties.zh文件修改filename.\u5b8b\u4f53simsun.…