2018 icpc 焦作站现场赛 E题题解

水题没人写题解,都直接上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。

import math

m,l=300,0
prime,a=[],[]
for i in range(0,m+1):
    a.append(1)
a[1]=0

for i in range(2,m+1):
    if a[i]:
        prime.append(i)
    for j in prime:
        if i*j>m:break
        a[i*j]=0
        if not i%j:break

T=int(input())
for o in range(0,T):
    n=int(input())
    h,k=1,0
    for i in prime:
        if h*i>n:break
        h*=i
        k+=1
    f=[1]
    for i in range(1,k+1):
        f.append(f[i-1]*(prime[i-1]+1))
    g=math.gcd(h,f[k])
    print(h//g,end='/')
    print(f[k]//g)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值