摘要: 《编程之美》读书笔记04: 1.8 小飞的电梯调度算法 假设电梯有n层,上楼要消耗能量k1,下楼要消耗能量k2,用a[i]表示要在第i层下的人数,Si为到i层时已经下(包括i层)的总人数,则总人数S=Sn。若用F(i)表示电梯在i层停时要消耗的总能量,则电梯在i+1层停时,有Si人要多下一层,(S-Si)人少上一层。则: F(i+1) = F(i) + k2*Si - k1*(S-Si) = F(i) + (k2+k1)*Si – k1*S = F(i) + G(i) (定义G(i) = (k2+k1)*Si – k1*S) 由于Si是递增的,G(i)也是递增的,当G(i) <= 0,F 阅读全文
posted @ 2011-03-22 23:16 flyinghearts 阅读(625) 评论(0) 推荐(0) 编辑
摘要: 题目:写一个程序,让用户来决定Windows任务管理器(Task Manager)的CPU占用率。程序越精简越好,计算机语言不限。例如,可以实现下面三种情况: 1. CPU的占用率固定在50%,为一条直线; 2. CPU的占用率为一条直线,但是具体占用率由命令行参数决定(参数范围1~ 100); 3. CPU的占用率状态是一个正弦曲线。 控制CPU占用率,不仅仅是出于好玩而已。以前的某些程序,特别是某些老游戏,在新的机器上运行速度太快,必须先给CPU降速,才能顺利运行那些程序,有个共享软件CPUKiller,就是专门弄这个的。 控制CPU占用率,因为要调用Windows的API,要考虑到多核、 阅读全文
posted @ 2011-03-22 23:13 flyinghearts 阅读(4638) 评论(1) 推荐(6) 编辑
摘要: 问题: N个1到13之间的自然数,能否通过加减乘除计算(每个数有且只能用一次)得到24? 计算24点常用的算法有:① 任取两个数,计算后,将结果放回去,再从剩下的数中任取两个,如此反复直到只剩下一个数;② 先构建前缀/后缀表达式,再计算该表达式;③ 用集合保存中间结果,集合间两两进行合并计算得到新集合(或者对给定的一个集合,对其所有的子集合进行合并计算)。 本文采用第一种方法。定义六种操作符:ADD、SUB、MUL、DIV、RSUB、RDIV,分别对应加、减、乘、除、反减和反除(反减/除:先交换两个数,再减/除)。 显然,取两个数计算时,六种计算结果可能有重复,可以对这6个结果进行去重(实 阅读全文
posted @ 2011-01-08 21:15 flyinghearts 阅读(4591) 评论(1) 推荐(1) 编辑
摘要: 实际上,用树的后序遍历就可以了。当访问到所求的节点A时,如果这两个节点不在一条线上,则它们必定分别在A的左子树和右子树上,后序遍历到第一个满足这个条件的节点就是所要求的节点A。另外,还必须对这两个节点在一条线上的情况,做特殊处理。代码: staticboollca(Node*root,intva,intvb,Node*&result,Node*parrent){//left/right左/右子树是否含有要判断的两节点之一boolleft=false,right=false;if(!result&&root-left)left=lca(root-left,va,vb,result,root 阅读全文
posted @ 2011-01-01 00:13 flyinghearts 阅读(2941) 评论(0) 推荐(0) 编辑
摘要: Trilogy公司的笔试题: 如果n为偶数,则将它除以2,如果n为奇数,则将它加1或者减1。问对于一个给定的n,怎样才能用最少的步骤将它变到1。 例如:n=11: ① ++n - 12 ② n/2 - 6 ③ n/2 - 3 ④ --n - 2 ⑤ n/2 - 1 共需5步。 最简单的方法就是用DP。设f(n)为所用的最少步骤。根据定义可得: 若n为偶数, f(n)=f(n/2) + 1; 若n为奇数, f(n)= min(f(n-1), f(n+1)) +1 = min(f((n-1)/2), f((n+1)/2)) +2 或者: f(2*k)=f(k)+1 f(2*k+1)= 阅读全文
posted @ 2011-01-01 00:12 flyinghearts 阅读(444) 评论(0) 推荐(0) 编辑
摘要: 多重背包O(N*V)算法详解(——使用单调队列) 多重背包问题: 有N种物品和容量为V的背包,若第i种物品,容量为v[i],价值为w[i],共有n[i]件。怎样装才能使背包内的物品总价值最大? 网上关于“多重背包”的资料倒是不少,但是关于怎么实现O(N*V)算法的资料,真得好少呀,关于“单调队列”那部分算法,又没说明得很清楚,看了几遍没看懂原理,只好自己动脑去想怎么实现O(N*V)算法。 若用F[i][j]表示对容量为j的背包,处理完前i种物品后,背包内物品可达到的最大总价值,并记m[i] = min(n[i], j / v[i])。放入背包的第i种物品的数目可以是:0、1、2……,可得: 阅读全文
posted @ 2011-01-01 00:10 flyinghearts 阅读(987) 评论(4) 推荐(1) 编辑
摘要: 问题: 一共有25匹马,有一个赛场,赛场有5个赛道,就是说最多同时可以有5匹马一起比赛。假设每匹马都跑的很稳定,不用任何其他工具,只通过马与马之间的比赛,试问最少得比多少场才能知道跑得最快的5匹马? 思路: 先将25匹马分成五组,进行五场比赛。第六场比赛可以考虑都取各个小组的第一名(或第二名)。假设都取各小组的第一名,根据这场比赛的排名,将原来的小组分别编号为a、b、c、d、e,并将原来的25匹马分别编号为: a1b1c1d1e1 a2b2c2d2e2 a3b3c3d3e3 a4b4c4d4e4 a5b5c5d5e5 其中Xi,X表示组的编号,i为在该组的排名,则有:a1 b1 c1 阅读全文
posted @ 2011-01-01 00:05 flyinghearts 阅读(1412) 评论(2) 推荐(1) 编辑
摘要: 题目: 给出sum、min、max和n四个正整数,请输出所有将sum拆分为n个递增的正整数(允许相等)之和,其中每个正整数k都满足:min = k = max。 在少侠的博客看到这道题,就随手做了下。该题与输出N个数取M个数的所有组合类似,只不过限定了M个数的和以及取值范围。可以先用贪心算法构造一个最小的组合,然后调整这个组合,得到下一个组合。显然应该从后往前找到一个数字,该数增加1,再调整该数后面的数。这个数就是:从后往前第一个与最后一个数的差值大于1的数(因为,如果差值小等于1,无法调整后面的数得到一个符合要求的组合)。 [代码] 阅读全文
posted @ 2010-12-31 23:39 flyinghearts 阅读(1175) 评论(0) 推荐(0) 编辑
摘要: 问题:如何高效的构建一个螺旋矩阵? 前面的文章讨论了两种螺旋矩阵。当N比较小时,可以用模拟法(测试代码中的build_1a和build_1b函数),另外可以将4个for循环体合并到一个(build_2a,build_2b和build_2c函数)。但N比较大时,由于不断的对内存跳跃式访问,CPU cache line命中率很低,定位和载入内存的开销相当大。一种解决方法是,直接计算每个位置对应的值(build_3a和build_3b函数);另一种解决方法则是:将每行拆分成三部份,一部分等于上一行同一列数值减1,中间部分是一断连续的递增或递减的数列(其起始和结束值可由公式算得),最后一部分的数等于上 阅读全文
posted @ 2010-12-31 23:35 flyinghearts 阅读(508) 评论(1) 推荐(0) 编辑
摘要: 问题 1 按顺时针方向构建(或螺旋访问)一个n * n的螺旋矩阵,效果见下图。 2 在不构造螺旋矩阵的情况下,给定坐标i、j值求其对应的值f(i, j)。 比如对6 * 6矩阵, f(2, 0) =19 f(2, 1) = 6 思路一 前一篇文章已经讨论了一类螺旋矩阵(由外向内),而这一类螺旋矩阵,则是由内向外扩散。这两类矩阵可以通过下面的方法相互转换。 由于是 n * n矩阵,对坐标(x,y)落在矩形的哪一条边上,可以直接使用x = y进行判断,原来的代码可以优化为: [代码] 思路二 将矩阵按1,1,2,2, … n-1,n-1, n 个数划分成几个矩形,比如:7*7矩阵( 阅读全文
posted @ 2010-12-25 10:53 flyinghearts 阅读(4104) 评论(6) 推荐(1) 编辑