• 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 }
  • 相关阅读:
    solaris 10 root忘记密码的解决方法
    c程序设计--指针与数组
    photoshop之色阶的使用
    Handling Errors Exceptionally Well in C++ 在C++中良好地捕获意外的错误
    自动换行 wordbreak:breakall和wordwrap:breakword
    透明度
    position:fixed在IE6下的实现
    JavaScript教程:常用DOM操作方法,JavaScriptDOM基本操作
    30 个免费的 UI 工具箱
    去掉虚线框兼容所有浏览器
  • 原文地址:https://www.cnblogs.com/1013star/p/10094741.html
Copyright © 2020-2023  润新知