E. Resistors in Parallel

E. Resistors in Parallel

[link](Problem - E - Codeforces)

题意

给你n个电阻,如果第i个电阻可以被一个大于1的完全平方数整除,他的阻值就是无穷,否则就是i。现在给你n个选择,每一个选择包含一个电阻集合,该集合由所有i的因数j,第j个电阻构成。让你选择其中一个集合,要求这些电阻并起来最小。

题解

并联的公式是 R = 1 1 R 1 + 1 R 2 + . . . + 1 R k R=\frac {1}{\frac 1{R_1} + \frac 1{R_2}+...+ \frac 1{R_k}} R=R11+R21+...+Rk11,我们要并联后的尽可能小,所以要分母尽可能大。第i个操作的集合所包含的电阻都是i的约数,任意一个数都可以被拆成一些质数的乘积,因为所有有平方因子的都是INF,所以对于重复的质因子是没有贡献的,只是和不同质因子有关。对于每一个质因子选于不选,构成的约数集合。化简以后分子就是前n个素数的乘积,分母是所有的约数相加,也就相当于一个二项式,也就是前n个素数,每一个素数加1然后相乘。

由于数据范围太大,所以用java的大数类更为方便。

Code

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    static int []a = new int[1005];
    static int N = 200005;
    static long []primes = new long[N];
    static long cnt = 0;
    static int []ok = new int[N];
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        primes[0] = 0;
        ok[0] = 1;
        ok[1] = 1;
        get_prime();
        int T = in.nextInt();
        while ((int) T -- > 0) {
            BigInteger n = in.nextBigInteger();
            BigInteger sum1 = new BigInteger("1");
            BigInteger sum2 = new BigInteger("1");
            int i = 0;
            while (true) {
                if (sum1.multiply(new BigInteger(String.valueOf(primes[i]))).compareTo(n) <= 0) {
                    sum1 = sum1.multiply(new BigInteger(String.valueOf(primes[i])));
                    sum2 = sum2.multiply(new BigInteger(String.valueOf(primes[i] + 1)));                    
                }
                else break;
                i ++;
            }
            BigInteger d = Gcd(sum1, sum2);
            sum1 = sum1.divide(d);
            sum2 = sum2.divide(d);
            System.out.println(sum1+"/"+sum2);
        }
    }
    static BigInteger Gcd(BigInteger a, BigInteger b) {
        if (b.compareTo(new BigInteger("0")) == 0)  return a;
        else return Gcd(b, a.mod(b));

    }
    static void get_prime() {
        for (long i = 2; i < N; i ++ ) {
            if (ok[(int)i] == 0) primes[(int)cnt ++] = i;
            for (long j = 0; primes[(int)j] < N / i; j ++ ) {
                ok[(int)(primes[(int)j] * i)] = 1;
                if ((i % primes[(int)(j)]) == 0) break;
            }
        }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值