【素数+大数】2018icpc焦作 E - Resistors in Parallel

题意:n个电阻,电阻Ri的阻值 r i = { ∞ if  i 是 平 方 数 i r_i = \begin{cases}\infty &\text{if } i是平方数 \\i\end{cases} ri={iif i
定义第i种电阻集合 S i = { j ∣ i % j = = 0 } S_i=\{j\mid i\%j ==0\} Si={ji%j==0},给定n,找出一个集合 S i S_i Si使得 S i S_i Si内电阻并联后阻值最小,输出最简分式。
思路:因为 x % d 2 = 0 x\%d^2=0 x%d2=0时电阻为0,所以我们只用考虑x不同因子的数量和大小,贪心的思考,质因子越小,越多,答案越小。所以我们要构造一个数 2 ∗ 3 ∗ 4 ∗ . . . ∗ p m a x ⩽ n 2*3*4*...*p_{max}\leqslant n 234...pmaxn,那么答案就是
a n s = 1 ∑ i = 1 , n % i = 0 n 1 i ans=\dfrac{1}{\sum_{i=1,n\%i=0}^{n}\dfrac{1}{i}} ans=i=1,n%i=0ni11
代码

import java.math.*;
import java.util.Scanner;

import javax.sound.midi.VoiceStatus;

public class Main {
	static long prime[]=new long[1005];
	static boolean isprime[] = new boolean[1005];
	static BigInteger fz[] = new BigInteger[1005],fm[] =new BigInteger[1005];
	static BigInteger array[]= new  BigInteger[1005];
	static int cnt,T,tot;
	static void getPrime() {
		for(int i=0;i<1005;i++) isprime[i] = false;
		cnt=0;
		for(int i=2;i<1005;i++) {
			if(!isprime[i])prime[++cnt]=i;
			for(int j=1;j<=cnt&&i*prime[j]<1005;j++) {
				isprime[(int)(i*prime[j])]=true;
			}
		}
	}
	static void init() {
		BigInteger Max =BigInteger.ONE;
		for(int i=1;i<=100;i++)Max=Max.multiply(BigInteger.TEN);
		BigInteger res=BigInteger.ONE;
		fz[0]=BigInteger.ONE;
		fm[0]=BigInteger.ONE;
		array[0]=BigInteger.ZERO;
		for(int i=1;i<=cnt;i++) {
			res=res.multiply(BigInteger.valueOf(prime[i]));
			array[i]=res;
			if(res.compareTo(Max)>0)break;
			fm[i]=fm[i-1].multiply(BigInteger.valueOf(prime[i]).add(BigInteger.ONE));
			fz[i]=fz[i-1].multiply(BigInteger.valueOf(prime[i]));
			BigInteger gcd=fz[i].gcd(fm[i]);
			fz[i]=fz[i].divide(gcd);
			fm[i]=fm[i].divide(gcd);
		}
	}
	public static void main(String[] args) {
		getPrime();
		init();
		BigInteger n;
		Scanner scanner =new Scanner(System.in);
		T=scanner.nextInt();
		while ((T--)!=0) {
			n=scanner.nextBigInteger();
			if(n.compareTo(BigInteger.ONE)==0) {
				System.out.println("1/1");
				continue;
			}
			int idx=0;
			for(int i=1;;i++) {
				if(n.compareTo(array[i])==0) {
					idx=i;
					break;
				}
				if(n.compareTo(array[i-1])>0&&n.compareTo(array[i])<0) {
					idx=i-1;
					break;
				}
			}
			if(fz[idx]==fm[idx])System.out.println("1/1");
			else System.out.println(fz[idx]+"/"+fm[idx]);
		}
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值