2018-2019 ACM-ICPC, Asia Jiaozuo Regional Contest E. Resistors in Parallel(大数,思维,打表)

链接 https://codeforces.com/gym/102028/problem/E

In this physics problem, what we are concerned about are only resistors. If you are poor at physics, do not worry, since solving this problem does not require you to have advanced abilities in physics.
Resistors are said to be connected together in parallel when both of their terminals are respectively connected to each terminal of the other resistors.
在这里插入图片描述

We have the following parallel resistor equation for k resistors with resistances R1, R2, …, Rk in parallel and their combined resistance R.
在这里插入图片描述

Now you have n resistors, the i-th of which has a resistance of ri ohms with the equation
在这里插入图片描述

You also have n selections, the i-th of which is a set of resistors Si such that
在这里插入图片描述

Please find a selection in which the resistors form a parallel resistor with the minimum resistance and output the reduced fraction of its resistance.

Input
The input contains several test cases, and the first line contains a positive integer T indicating the number of test cases which is up to 100.

For each test case, the only one line contains an integer n, where 1 ≤ n ≤ 10100.

Output
For each test case, output a line containing a reduced fraction of the form p/q indicating the minimum possible resistance, where p and q should be positive numbers that are coprime.

Example
input
3
10
100
1000
output
1/2
5/12
35/96

题意
给你一个数n,表示有1到n种方案可选,第i次方案有i的因子的电阻,这些电阻并联,如果第i个电阻能被平方数整除,则电阻无限大,求这些方案中总电阻最小的。

思路
打表,1,2,6,30,210,2310,30030,510510
对应的分数也是有规律
prime[i]/(prime[i]+1) * prime[i+1]/(prime[i+1]+1) * … * prime[n]/(prime[n]+1)
现在的问题就来了,数据是10^100,大数问题,我们可以用c++的大数模板,但是没必要,我们可以用python或java做,具体看代码。

代码

import java.math.*;
import java.util.*;
public class zr {

	public static void main(String[] args) {
		final int N = 1000+5;
		//init()
		int prime[] = new int[N];
		int vis[] = new int[N];
		int cnt = 0;
		for(int i=2;i<=1000;i++) {
			if(vis[i]==0) prime[++cnt]=i;
			for(int j=1;j<=cnt;j++) {
				if(i*prime[j]>1000) break;
				vis[i*prime[j]]=1;
				if(i%prime[j]==0) break;
			}
		}
		Scanner cin = new Scanner(System.in);
		int Case,v=2;
		BigInteger n,fz=BigInteger.ONE,fm=BigInteger.ONE,t;
		Case= cin.nextInt();
		while(Case>0) {
			v=2;
			fz=BigInteger.ONE;fm=BigInteger.ONE;
			n=cin.nextBigInteger();
			for(int i=1;fz.compareTo(n)<=0;i++) {
				fz=fz.multiply(BigInteger.valueOf(prime[i]));
				fm=fm.multiply(BigInteger.valueOf(prime[i]+1));
				v=prime[i];
			}
			fz=fz.divide(BigInteger.valueOf(v));
			fm=fm.divide(BigInteger.valueOf(v+1));
			t=fz.gcd(fm);
			fm=fm.divide(t);
			fz=fz.divide(t);
			System.out.println(fz+"/"+fm);
			Case--;
		}
	}
		
}

import math
prime=[]
vis=[0 for i in range(1000+1)]
for i in range(2,1000):
       if vis[i]==0:
              prime.append(i)
       for p in prime:
              if i*p>1000:
                     break
              vis[i*p]=1
              if i%p==0:
                     break
Case = int(input())
while Case > 0:
       n=int(input())
       fz = int(1)
       fm = int(1)
       v = 2
       cnt = 0
       for p in prime:
              fz = fz * p
              fm = fm * (p+1)
              v = p
              if fz > n:
                     break
       fz = fz // (v)
       fm = fm // (v + 1)
       t = math.gcd(fz,fm)
       fz = fz // t
       fm = fm // t
       print(str(fz)+'/'+str(fm))
       Case-=1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值