资讯详情

java实现 ----电容充电

有一个由电容组成的计算器,每个电容组件都有最大容量值(正整数)。 对于单个电容器,操作说明如下: 指令1:放电操作-清除电容器当前电量值 指令2:充电操作-将当前电容补充到最大容量值 两个电容A和B,有如下操作指令: 指令3:转移操作-从A中尽可能多地转移电量B,转移不会有电量损失。如果能充满B的最大容量,剩余电量仍将留在A中

现在已知有两个电容,最大容量是a和b其初始状态为0,希望通过一系列操作,使其中一个电容器无论哪一个)中的电量值等于0c(c也是正整数),这一系列操作中使用的正整数)M,无论如何操作,都不可能完成,此时定义M=0。 显然,每组都确定了a、b、c,会有一个M对应。

输入描述: 每组试样的输入格式为: 第一行是正整数N 从第二行开始,每行由三个正整数组成a、b、c,一共有N组 输出描述: 输出为N行,每行打印每组对应M 备注: 数据范围:

N:0<N<100  a、b、c:  0<a、b、c<10^5(50%)  0<a、b、c<10^7(30%)  0<a、b、c<10^9(20%) 

输入 2 3 4 2 2 3 4 4 0 至少需要4个指令才能完成(3、4、2): (最大容量为3的是A号电容,另一个是B号电容) 1. 充电A 2. 转移A->B 3. 充电A 4. 转移A->B 此时A中当前电量为2,操作完成,因此输出4。 显然不可能完成(2、3、4),输出0。

import java.util.Scanner;  /** * 请参考参考网站进行分析: * https://blog.csdn.net/u014251675/article/details/81572135 * * @author Liu * @date 2018-08-16 11:51 */ public class DiaoRongChongDian { 
            public static void main(String[] args) {         Scanner sc = new Scanner(System.in);         int N = sc.nextInt();         long[] A = new long[N];         long[] B = new long[N];         long[] C = new long[N];         // 输入数据         for (int i = 0; i < N; i  ) {             A[i] = sc.nextLong();             B[i] = sc.nextLong();             C[i] = sc.nextLong();         }         // 开始处理数据         for (int i = 0; i < N; i  ){             long a = A[i];             long b = B[i];             long c = C[i];             long[] d = ex_gcd(a, b);             // 如果c 大于 a和b 亦或是c%d不是0意味着不可能实现             if (c>a&&c>b||c%d[0]!=0){                 System.out.println(0);                 continue;             }else if (a==c||b==c){     
      //c 恰好是b或a,一次就够了                 System.out.println(1);                 continue;             }else {                 long x = d[1];                 long y = d[2];                 if (d[2]>0){                     long temp2 =x;
                    x = y;
                    y = temp2;
                    long temp = a;
                    a = b;
                    b = temp;
                }
                // 使ax + by = c (d是c的因子,即对上面式子ax + by = d两边同时乘以c / d)
                long a2 = a/d[0];
                long b2 = b/d[0];
                x *= c/d[0];
                y *= c/d[0];

                /* 最小化|x|+|y| * ax+by=c的全部整数解为: * x+kb/gcd(a,b) * y−ka/gcd(a,b), k=...,−2,−1,0,1,2,... * */

                long k = x/b2;
                x -= k*b2;// 使这组(x, y)最接近0(x > 0时的整数解)
                y += k*a2;
                long res ;
                if (c>a){
                    res = 2*(x-y);
                }else {
                    res = 2*(x-y-1);
                }
                x -= b2;// 使这组(x, y)最接近0(y > 0时的整数解)
                y += a2;
                if (c>b){
                    res = Math.min(res,2*(y-x)); // 上文分析中假设x > 0,这里y > 0
                }else {
                    res = Math.min(res,2*(y-x-1));
                }
                System.out.println(res);
            }

        }

        sc.close();

    }
    /** * 扩展欧里几何 * 存在整数对 x,y ,使得 gcd(a,b)=ax+by * * @param a * @param b * @return 第一个值是最大公约数,第二个值表示C++语言实现中的x,第三个值表示y。 */
    public static long[] ex_gcd(long a, long b) {
        long ans;
        long[] result = new long[3];
        if (b == 0) {
            result[0] = a;
            result[1] = 1;//x
            result[2] = 0;//y
            return result;
        }
        long[] temp = ex_gcd(b, a % b);
        ans = temp[0];//ans 相当于t
        result[0] = ans;
        result[1] = temp[2];
        result[2] = temp[1] - (a / b) * temp[2];
        return result;
    }
    //普通的最大公约数的求法
    public static long common_gcd(long a, long b) {
        return a % b == 0 ? b : common_gcd(b, a % b);
    }
}

引用https://blog.csdn.net/u014251675/article/details/81572135块内容

标签: gcd电容

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台