水题没人写题解,都直接上Java代码……那我写一个。
计蒜客题面:https://nanti.jisuanke.com/t/A2203
题意:如果i是完全平方数(>=4)的倍数,那么i号电阻的阻值为无穷大,否则为i。
现在有编号为1~n的集合,每个集合包含若干个电阻,编号为i的集合包含所有编号为i的约数的电阻。求一个集合,使该集合内所有电阻的并联阻值最小。
关键的来了:n<=10100
首先,对于一个电阻,如果它能改变总电阻,那么着它的阻值不是无穷大,因此它的每个质因子最多被乘了一次。所以对于每个电阻的集合,它的编号的约数中,只有1、质因数、以及若干个不同质因数的积是有效的。另外,如果一个数的约数包含了若干个质因数,那么这个数的约数也必然包含这些质因数的积。 这样,只要选出积不超过n的若干个质数,再加上公共约数1,就是要找的集合。
那么选取哪些质数呢?从让阻值尽量大的角度来讲,在质因子数量相同的情况下,应当选择尽量小的质数。以比较集合6和集合10为例,6=1×2×3,10=1×2×5,显然电阻5和(2×5=10)两个电阻都比3和(2×3=6)的阻值大,因此质因子5不如质因子3优。另外,由于要选的集合编号不超过n,在质因子数量相同的情况下,如果能选较大的质因子,必然能选编号较小的质因子。因此选质因子的策略为:在质因子的积不超过n的前提下,尽量选取最小的质因子,即依次选取2,3,5,7……
然后就是计算总电阻。题目给了电阻公式,此处R1,R2,R3,R4……Rk依次等于1,2,3,5……(2×3×5×……×p),其中p为最大的质因子。
上下同时乘以Rk,得到:R=Rk/(1+2+3+5+……+p+2×3+2×5+3×5+……+2×3×5+……+Rk)
分母中,对于每一个含有p的项,提取p,得:p×(1+2+3+5+……+2×3+2×5+3×5+……)+(1+2+3+5+……+2×3+2×5+3×5……)=(p+1)×(1+2+3+5+……+2×3+2×5+3×5+……)
观察发现,(p+1)的系数是不取p的情况下的分母值。那么这个分母就形成了递推式,后一项是前一项的p+1倍,第一项为1。这样用递推式求出分母,约分即可。
用欧拉筛预处理出前若干项质数,它们的积至少要超过n的最大值10100,经过验证,求出前300项质数已经足够了。
然后就是py= = Java不会(而且高精度类似乎比较糟),c++……考场手打高精度???
人生苦短,我用python。
1 | import math |