一道有挑战性的题

本文内容遵从CC版权协议 转载请注明出自:   http://blog.csdn.net/masterluo

 

从1~N这N个数按照下面的排法一直排下去,规定S(N)为左上角是1,右下角为N的这个大矩形里面的所有小矩形里的数的和。例如S(12)就表示图中12个绿色格子的数的和。现在给定N,让你求S(N)。

 


这道题是TopCoder SRM454 DIV1 Level3的题变过来的,事情整个发展过程是这样的,我看了题中定义了S(N)之后就没看了……以为就是求S(N),原题实际上是要求S(N)这个矩形里的数的所有S(x)的和。如N=9,则结果为sigm(S(x)) x∈{1,2,9}.写完了代码才发现程序与题意牛头不对马嘴……好吧,先想想我看错的那种题是怎么解的,再来正式解决TC上那道原题吧。


首先想两个问题:一是如果知道一个数,能不能快速求出这个数的位置呢?二是能不能快速求出一个位置的数是多少呢?答案都是肯定的,并且能够直接求出来。怎么求呢?第一个概据X一定在ceil(sqrt(x))为边长的一个正方形内。如7一定在边长为3的正方形的边上。这样再概据奇偶性质可以求出数所在的行与列。求(r,c)位置上的也可以概据同样的道理,因为(r,c)边界上的最大的数据可以根据max(r,c)*max(r,c)求出来。这样再根据奇偶性质可求出数是多少。


但是这还不够,因为N高达10^10,显然不能一个一个数的枚举,看这个数是不是落在我们给定的数所组的矩形内。还可以发现什么规律呢?如果给定的数在对主角线上,那么实际上就是求一个正方形内的数是多少。而一个正方形内的数又包含了从1开始的所有的数,那么直接可以根据等差数列求和公式求出来。如S(7)=1+2+3+…+9, S(3)=1+2+3+4。如果我们要求的和不是在一个正方形内怎么办呢?如例中说的S(12),它是一个宽为4,高为3的一个矩形。有规律?如果宽大于高,那么除了一个正方形外,还会剩余一些列,那些列每列上都是一个等差数列,如果宽小于高,那么除了一个正方形外,还会剩余一些行,这些行都是一个等差数列。由于剩余的列与列不会超过sqrt(N),那么我们可以一列一列(或一行一行)的求出所以多出来的值,再与原来的正方形拼接求和即可。如S(12),除了那个1-9的一个正方形外,还剩余一行10-11-12.由于上面所说的可以快速求一个位置的数。那么问题得到了完美解决,复杂度为O(sqrt(N))。


再回到原题上来,原题似乎没有这么简单了。要求这个矩形内所有的S(x)的和,穷举显然是不可能的。因为在最坏情况下可以达到10^15的复杂度。一个比较简单的规律被发现,如果矩形大小在(R,C),那么在矩形内位置为(r,c)这个位置的值被加了(R-r+1)*(C-c+1)次。因为以它为左上角,以(R,C)为右下角的每个S(x)值都包含它。


如果先把每个格子里的值与它会出现的次数相乘,会不会通过转化转化为第一层那种可以通过一行或一列的方式求出整一行的值呢?我们把所有情况列出来发现只有四种:横向递增,横向递减,纵向递增,纵向递减。 今天上软件体系结构的时候把公式推出来了。简单说一下思想吧:我们把一列的值列出来后,发现每一列都可以表示为三个数的乘积,而这三个数中有一个数会是相同的,先将它提取出来。剩下的两项都是等差列,即两个等数差列每些对应项的乘积。把这个式子扩展从第一项开始,后与n*n这个数列对比可以发现通过增加或减少这个数,可以提取出另一个等差数与一个常数项的乘积。这样问题就完美解决了。晚上再贴图在本子上面推导的过程吧。

 

如果是横向递减速的话,那中间那一堆就不是相减速的关系,而是相加的关系。关于纵向递加与递减速可以相向比较简单同样的表达式。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值