标签:
给定正整数N,函数F(N)表示小于等于N的自然数中1和2的个数之和,例如:1,2,3,4,5,6,7,8,9,10序列中1和2的个数之和为3,因此F(10)=3。输入N,求F(N)的值,1=<N<=10^100(10的100次方)若F(N)很大,则求F(N)mod20123的值。3
5
看了一份别人的代码,十分简略,不明白怎么做的,就发到了论坛里,有人给讲解了,讲得很棒
比如输入12345,那么先算F(1),再由F(1)算出F(12),依次再算出F(123),F(1234),F(12345);
主要计算的就是rslt=(rslt-cnt)*10+num*2+cnt*(t+1)+min(t,2);这一句了。
rslt是结果;num是实际输入的数;cnt是num这个数中1,2的数量;
首先认为已经算出了F(12)=rslt,需要算F(123)
1.显然12变成了12X的形式,所以原来1-11中每一个数都可以加上一个个位(因为不知道个位是不是9,所以最后一个12不能乘10,以后单独计算),而个位是从0-9,所以原来的每个数都有10中变化,而最后一个数12的1,2的数量为cnt,所以有(rslt-cnt)*10,;
(比如比12小的有1,2的数是:1,2,10,11,扩大十倍后,有10-19,20-29,100-109,110-119,每个数各对应十个数,他们原本的的1和2被加了十次,所以乘以10)
2.上一步中余有一个12没有计算,显然12X这个数的个位只能是0-3,所以有cnt*(t+1);
(t是X位的数,cnt是12的1,2个数,为2,t从0开始,所以是cnt*(t+1)个)
4.上面的计算中都没有考虑对个位为1,2的计数,10-120中个位为1,2的显然是每10个数中有2个,所以有num*2
3.第一步还有一个0没计算,若为0则只有个位有值,直接判断就好了,min(t,2);
九度OJ 1491 清华大学2012机试 《求1和2的个数》
标签:
原文地址:http://blog.csdn.net/nishizhenlige/article/details/43671705