算法基础课第六章。解决一些问题。(二)

简介: 算法基础课第六章。解决一些问题。(二)

第九题特殊的同余方程-逆元


package 第六章数学问题;
import java.util.Scanner;
/**
 * 2022/3/26
 * 6.10 特殊的同余方程-逆元
 * @author MZFAITHDREAM
 *模的逆元
 *ax=1
 *x=1/a
 *AX=1(% mod)
 *AX+BY=M
 *
 */
public class Test10 {
  public static void main(String[] args) {
//  创建Scanner对象输入内容
     Scanner scanner = new Scanner(System.in);
          int T = scanner.nextInt();
          for (int i = 0; i < T; i++) {
              int n = scanner.nextInt();
              int b = scanner.nextInt();
              try {
                  MyGcd.inverseElement(b, 9973);
                  long x = MyGcd.x;
                  System.out.println(x*n%9973);
              } catch (Exception e) {
                  // TODO: handle exception
              }
          }
      }
      private static class MyGcd{
          static long x;
          static long y;
          public static long gcd(long m, long n) {
              return n == 0 ? m : gcd(n, m % n);
          }
          public static long ext_gcd(long a,long b){
              if (b==0) { 
                  x = 1;
                  y = 0;
                  return a;
              }
              long res = ext_gcd(b, a % b);
              long x1 = x;
              x = y;
              y = x1 - a / b * y;
              return res;
          }
          public static long linearEquation(long a, long b, long m) throws Exception {
              long d = ext_gcd(a, b);
              if (m % d != 0) {
                  throw new Exception("无解");
              }
              long n = m / d;
              x *= n;
              y *= n;
              return d;
          }
          public static long inverseElement(long a, long mo) throws Exception {
              long d = linearEquation(a, mo, 1);// ax+mo*y=1
              x = (x % mo + mo) % mo;// 保证x>0
              return d;
          }
      }
  }


第十题:很有意思的同余方程组。


package 第六章数学问题;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
 * 6.11 很有意思的同余方程组
 * @author MZFAITHDREAM
 *
 */
public class Test11 {
  public static void main(String[] args) throws Exception {
         Scanner scanner = new Scanner(System.in);
         int t = 1;
         List<Long[]> aList = new ArrayList<Long[]>();
         List<Long> dList = new ArrayList<Long>();
         while(scanner.hasNext()){
             Long []a = {scanner.nextLong(),scanner.nextLong(),scanner.nextLong()};
             Long d = scanner.nextLong();
             if (a[0]==-1&&a[1]==-1&&a[2]==-1&&d==-1) {
                 break;
             }else {
                 aList.add(a);
                 dList.add(d);
             }
         }
         for (int i = 0; i < aList.size(); i++) {
             Long[] a = aList.get(i);
             long d = dList.get(i);
             Long[] m = { (long) 23, (long) 28, (long) 33 };
             long res = MyGcd.linearEquationGroup(a, m);
             while (res <= d) {
                 res += 21252;
             }
             System.out.println("Case " + (t++) + ": the next triple peak occurs in " + (res - d) + " days.");
         }
     }
     private static class MyGcd {
         static long x;
         static long y;
         /**
          * 
          * 
          * @param a 余数组成的数组
          * @param m 模组成的数组
          * @return
          * @throws Exception
          */
         public static long linearEquationGroup(Long[] a, Long[] m) throws Exception {
             int len = a.length;
             if (len == 0 && a[0] == 0)
                 return m[0];
             for (int i = 1; i < len; i++) {
                 // 这里往前看是两个方程
                 long a2_a1 = a[i] - a[i - 1];
                 long d = linearEquation(m[i - 1], -m[i], a2_a1);
                 // 现在的x是y1,用y1求得一个特解
                 long x0 = a[i - 1] + m[i - 1] * x;
                 long lcm = m[i - 1] * m[i] / d;
                 a[i] = (x0 % lcm + lcm) % lcm;// x0变成正数
                 m[i] = lcm;
             }
             // 合并完之后,只有一个方程 : x = a[len-1] (% m[len-1])
             //long d = linearEquation(1, m[len-1], a[len-1]);
             return a[len - 1] % m[len - 1];
         }
         public static long inverseElement(long a, long mo) throws Exception {
             long d = linearEquation(a, mo, 1);
             x = (x % mo + mo) % mo;
             return d;
         }
         public static long linearEquation(long a, long b, long m) throws Exception {
             long d = ext_gcd(a, b);
             // m不是gcd(a,b)的倍数,这个方程无解
             if (m % d != 0)
                 throw new Exception("无解");
             long n = m / d;// 约一下,考虑m是d的倍数
             x *= n;
             y *= n;
             return d;
         }
         public static long ext_gcd(long a, long b) {
             if (b == 0) {
                 x = 1;
                 y = 0;
                 return a;
             }
             long res = ext_gcd(b, a % b);
             long x1 = x;// 备份x
             x = y;// 更新x
             y = x1 - a / b * y;// 更新y
             return res;
         }
     }
}


第十一题素数的测试及质因数分解。


package 第六章数学问题;
import java.util.HashMap;
import java.util.Map;
/**
 * 6.12 素数的测试及质因数分解
 * 
 * @author MZFAITHDREAM
 *
 */
public class Test12 {
  /**
  * @author MZFAITHDREAM
  * @param args
  */
  public static void main(String[] args) {
   /**
    * @author MZFAITHDREAM
    * 
    * 判断数字是否为素数
    */
         boolean res = isPrime(7);
         System.out.println(res);
         /**
          * @author MZFAITHDREAM
          * 质因数分解案例
          */
         Map<Integer, Integer> map = primeFactor(100);
         StringBuilder sb = new StringBuilder();
         for(Map.Entry<Integer, Integer> entry:map.entrySet()){
             int k = entry.getKey();
             int v = entry.getValue();
             for (int i = 0; i < v; i++) {
                 sb.append("*"+k);
             }
         }
         System.out.println(map);
         System.out.println(sb.substring(1));
     }
     /**
      * @author MZFAITHDREAM
      * 检查num是不是素数
      * 2~根号n
      */
     public static boolean isPrime(long num){
         for (int i = 2; i*i <= num; i++) {
             if (num%i==0) {
                 return false;
             }
         }
         return true;
     }
     /**
      * 质因素分解:100 = 2*2*5*5
      * map是质因数-出现次数的映射
      */
     public static Map<Integer, Integer> primeFactor(int num){
         Map<Integer, Integer> map = new HashMap<>();
         for (int i = 2; i*i <= num; i++) {
             while(num%i==0){
                 Integer v = map.get(i);
                 if (v==null) { 
                     map.put(i, 1);
                 }else {
                     map.put(i, v+1);
                 }
                 num /= i;
             }
         }
         return map;
     }
}


第十二题素数的筛法


package 第六章数学问题;
import java.math.BigInteger;
/**
 * 6.13 素数的筛法
 * @author MZFAITHDREAM
 *
 */
public class Test15 {
  public static void main(String[] args) {
        long now = System.currentTimeMillis();
        f(100002);
        System.out.println("耗时:" + (System.currentTimeMillis() - now) + "ms");
        now = System.currentTimeMillis();
        BigInteger bigInteger = new BigInteger("1");
        for (int i = 1; i <= 100002; i++) {
            bigInteger = bigInteger.nextProbablePrime();
        }
        System.out.println(bigInteger);
        System.out.println("耗时:" + (System.currentTimeMillis() - now) + "ms");
        now = System.currentTimeMillis();
        int count = 0;
        long x = 2;
        while(count<100002){
            if (isPrime(x)) {
                count++;
            }
            x++;
        }
        System.out.println(x-1);
        System.out.println("耗时:" + (System.currentTimeMillis() - now) + "ms");
    }
  /**
  * 
  * @param num
  * @return
  */
    public static boolean isPrime(long num){
        for (int i = 2; i*i <= num; i++) {
            if (num%i==0) {
                return false;
            }
        }
        return true;
    }
    /**
     * 
     * @param N 第N个素
     */
    private static void f(int N){
        int n = 2;
        while(n/Math.log(n)<N){
            n++;
        }
        int []arr = new int[n];
        int x = 2;
        while(x<n){
            if (arr[x]!=0) {
                x++;
                continue;
            }
            int k=2;
            while(x*k<n){
                arr[x*k] = -1;
                k++;
            }
            x++;
        }
        int sum = 0;
        for (int i = 2; i < arr.length; i++) {
            // 是素数,计数+1
            if (arr[i] == 0) {
                // System.out.println(i);
                sum++;
            }
            if (sum == N) {
                System.out.println(i);
                return;
            }
        }
    }
}


第十三题快速幂运算


package 第六章数学问题;
/**
 * 6.14 快速幂运算
 * 
 * @author MZFAITHDREAM
 *
 */
public class Test16 {
  public static void main(String[] args) {
        System.out.println(ex2(2, 9));
    }
    /**
     * 
     * @param a
     * @param n
     * @return
     */
    public static int ex(int a,int n){
        if(n==0)return 1;
        if(n==1)return a;
        int temp = a; // a的1次方
        int res = 1;
        int exponent = 1;
        while((exponent<<1)<n){
            temp = temp * temp;
            exponent = exponent << 1;
        }
        res *= ex(a,n-exponent);
        return res * temp;
    }
    /**
     * 快速幂  O(lgn)
     */
    public static long ex2(long n,long m){
        if(n==0) return 1;
        long pingFangShu = n; // n 的 1 次方
        long result = 1;
        while (m != 0) {
            // 遇1累乘现在的幂
            if ((m & 1) == 1)
                result *= pingFangShu;
            // 每移位一次,幂累乘方一次
            pingFangShu = pingFangShu * pingFangShu;
            // 右移一位
            m >>= 1;
        }
        return result;
    }
}
相关文章
|
算法
【AcWing算法基础课】第五章 动态规划(未完待续)(3)
当然,一个人能够滑动到某相邻区域的前提是该区域的高度低于自己目前所在区域的高度。
114 0
|
存储 人工智能 算法
【AcWing算法基础课】第四章 数学知识(未完待续)(3)
根据下面公式来预处理出等式右边的组合数的值,那么等式左边就可以用等式右边已经算过的值来进行计算(有点像dp)。
82 0
|
人工智能 算法 BI
【AcWing算法基础课】第四章 数学知识(未完待续)(2)
从2到n枚举每个数,删掉其所有的倍数,枚举完之后,没有被删掉的数为质数。
116 0
|
人工智能 算法
【AcWing算法基础课】第一章 基础算法(部分待更)(3)
输入n个字符串(不含空格),由空格隔开。每行依次输出每个字符串。
79 0
|
算法 存储 内存技术
【AcWing算法基础课】第三章 搜索与图论(2)
特点:尽可能先向纵深方向搜索。使用stack实现。所需空间O(h)(h为深度)。不具有“最短性”。
87 0
【AcWing算法基础课】第三章 搜索与图论(2)
|
存储 人工智能 移动开发
【AcWing算法基础课】第一章 基础算法(部分待更)(2)
除法是从最高位开始算,可以正序存储,但是为了与加减乘统一,以及题目中存在四则运算时比较方便,也使用倒序存储每位信息。
128 0
|
存储 算法 C++
【AcWing算法基础课】第二章 数据结构(部分待更)(3)
路径压缩:查找时,如果还没有找到目标值的父结点时,将路径上每个点的父结点,在向上寻找过程中更新记录。
102 0
|
算法
【AcWing算法基础课】第五章 动态规划(未完待续)(1)
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且 总价值最大 。
67 0
【AcWing算法基础课】第五章 动态规划(未完待续)(1)
|
算法 存储 内存技术
【AcWing算法基础课】第三章 搜索与图论(3)
特点:尽可能先向纵深方向搜索。使用stack实现。所需空间O(h)(h为深度)。不具有“最短性”。
117 0
【AcWing算法基础课】第三章 搜索与图论(3)
|
算法 存储 C++
【AcWing算法基础课】第三章 搜索与图论(1)
特点:尽可能先向纵深方向搜索。使用stack实现。所需空间O(h)(h为深度)。不具有“最短性”。
75 0
【AcWing算法基础课】第三章 搜索与图论(1)