整数问题
http://hero.youkuaiyun.com/Question/Details?ID=192&ExamID=187
题目详情
如果一个数能够被组成它的各个非0数字整除,则称它是完美数。例如:1-9都是完美数,10,11,12都是完美数,但是13就不是完美数(因为13不能被组成它的数字“1”和“3”整除)。
现在给定正整数x,y,求x和y之间(包含x和y)一共有多少个完美数。输入数据1<=x<=y<=2000000000。
例如:
x = 1, y = 13,输出12;
x = 13,y = 13,输出0;
x = 100,y = 1000,输出106。
题解():
第一次瞅见这道题,没多少思路,后来鉴于庞果网内部的问题还是别的原因,这道题就从首页消逝了,今天又瞅见了,于是再仔细想了想,发现依然是水题一枚。
这道题,依然是数据规模的坎,规模太大,不能随便枚举。其实,这些规模大的题目,反而相对容易,目标很明显,如何减少计算量!!
第一点,发现规律:
总共才9个数字,而且数字1根本不用判断,含有1的数字肯定能被1整除。于是只剩下8个数字[2-9]。然后,有些数包含了所有的这8个数字,有些数字可能只包含部分,因此这里有2^8个状态,描述这8个数字可能被包含的状态。
OK,继续,每个数,如果它包含某些数字,那么它一定要被这些数字整除。于是,想到需要记录它对每个数字的取模的余数,然后根据余数为0判断是否被整除。用r[i]表述x对数字i的余数,即 r[i]=x%i,(i=2,3,4,5,6,7,8,9).
很好,这里又有规律了:知道了r[4]就不用记录r[2]了,因为r[2]=r[4]%2。
同理,可以踢除一些不需要记录的数字:
①9剔除3
②8剔除2和4
③8 9 剔除 6
对于①②,比较好理解,直接的倍数关系。对于③,需要转一个弯,因为8中含有因子2,9中含有因子3,因此根据【中国剩余定理】:
x=9*k9 + r9 (k9<9)
x=8*k8 + r8 (k8<8)
那么x一定可以表述为x=72*k + r0, (r0<72)
72是6的倍数,因此,如果计算出了r0,则就可以算出x%6
至于怎么计算r0,参考度娘的解答。
推导到了这一步,可以估算一下复杂度:
2000000000,共10位 --i
8个数字,共2^8个状态 -- S
记录的余数组合情况,共max(r[9]* r[8]* r[7]* r[5]) = 9*8*7*5=2520 --R
总共合计起来=10*256*2520= 6451200
靠谱!!!!
第二步,数位dp算法
对待统计的数,从高位向地位枚举
枚举第i位,记录高于第i位的状态S,余数组合情况R,然后很容的转移到第i-1位。
i<0 则判断是否S和R组合是否符合条件。
由此,完美解决!