2018ACM-ICPC焦作站E题Resistors in Parallel

Resistors in Parallel

题目:

       ACM-ICPC Jiaozuo Onsite 2018

    

 

题解:因为题目数据范围很大,所以猜测应该是一个区间一个固定的最小值。问题转换成了如何求某个最小值影响的区间。坤神一眼看出,应该通过素数求,因为一个数的因子有很多,但是所有的因子都可以通过该数的素因子推出来。比如6的因子有1 2 3 6,素因子有2 3,所以1=2^0*3^0,2=2^1*3^0,3=2^0*3^1,6=2^1*3^1。又因为并联电阻并联越多阻值越小,所以在某些数有相同的素因子的情况下,这些素因子组成的因子越多越好,但是题目说能被d*d (d>=2)整除的因子的电阻为无穷大,并联相当于没有,所以对总电阻的贡献值为0,可以不考虑。所以以30为例,30的素因子有2 3 5,所以我们只需要计算x=1+2+3+5+2*3+2*5+3*5+2*3*5,(计算这个也是找规律,2 3 5中有 1个1 1个2 1+1*2个3 1+2+(1+2)*3个5……每个存在的素因子的个数为前面所有素数的总和(orz贤哥tql))即可,然后只以2 3 5为素因子的区间最小值就是30/gcd(30,x) / (x/(gcd(30,x))).最后对于每次输入的N,以素数从小到大累乘的方式找到n以内数最大组成的素因子。例如n=100 2*3*5<=100,2*3*5*7>100,所以100就在只以2 3 5为素因子的区间里。

因为这个题的数据范围很大,所以用Java写。

 1 import java.util.*;
 2 import java.math.*;
 3 public class Main{
 4     static Scanner cin = new Scanner(System.in);
 5     static BigInteger [] dp = new BigInteger[1100];
 6     static boolean [] prime = new boolean[11000];
 7     static int[] nums = new int [11000];
 8     static int cnt = 0;
 9     public static void init() {
10         prime[1] = true;
11         for(int i = 1 ;i<=1000;i++) {
12             prime[i]=true;
13         }
14         for(int i = 2; i <= 1000; i++) {
15             if(prime[i]) {
16                 nums[++cnt] = i;
17                 for(int j = i+i; j <= 1000; j +=i) {
18                     prime[j] = false;
19                 }
20             }
21         } 
22     }
23     public static void main(String[] args) {
24         init();
25         int casen = cin.nextInt();
26         while(casen-->0) {
27             BigInteger n = cin.nextBigInteger();
28             int k;
29             dp[0] = BigInteger.ONE;
30             BigInteger yinzi = BigInteger.ONE;  
31             for(k = 1; (yinzi.multiply(BigInteger.valueOf(nums[k])).compareTo(n)<=0);k++) {
32                 yinzi = yinzi.multiply(BigInteger.valueOf(nums[k]));
33             } 
34             k--;
35             BigInteger sum = BigInteger.ONE;
36             for(int i = 1;i <= k; i++) {
37                 dp[i]=dp[i-1].add(dp[i-1].multiply(BigInteger.valueOf(nums[i])));
38             }
39             BigInteger gcd = yinzi.gcd(dp[k]);
40             System.out.println(yinzi.divide(gcd)+"/"+dp[k].divide(gcd));
41         }
42     }
43 
44 }

转载于:https://www.cnblogs.com/1013star/p/10094741.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值