分享|【数论概论】第三部分
480
2024.05.03
2024.05.13
发布于 未知归属地
  1. 第五章 整数性与最大公因数

    1. 习题5.1
    2. 习题5.2
    3. 习题5.3
    4. 习题5.4
    5. 习题5.5
    6. 习题5.6
    7. 代码-GCD与LCM
    8. 代码-冰雹数列
  2. 第六章 线性方程与最大公因数

    1. 习题6.1
    2. 习题6.2
    3. 习题6.3
    4. 习题6.4
    5. 习题6.5
    6. 习题6.6
    7. 行列式求解GCD
    8. 代码-乘法逆元GCD法
  3. 其他

第五章 整数性与最大公因数

习题5.1

​ 应用欧几里得算法计算下述最大公因数。

(a)
(b)

习题5.2

​ 编写程序计算两个整数 a 与 b 的最大公因数 gcd(a, b), 即使 a 与 b 中的一个等于零,程序也应该运行,但要确保 a 与 b 都是 0 时不会出现死循环。

见代码部分

习题5.3

是将欧几里得算法应用于 a 与 b 得到的相继余数,证明每两步会缩小余数至少一半。换句话说,验证:

由此证明欧几里得算法在至多步终止,其中是以2为底的对数。特别地,证明步数至多是b的位数的7倍。(提示:的值是多少?)

证:,又

习题5.4

​ 如果 m 与 n 都整除L,则数 L 被称为 m 与 n 的公倍数。最小的这种 L 被称为 m 与 n 的最小公倍数,记为 .例如,.

  • (a) 求下述最小公倍数。

    • (i) (ii) (iii) (iv)
  • (b) 对于在(a)中计算的每个, 比较的值,试找出他们之间的关系。

  • (c) 证明你说发现的关系对所有 m 与 n成立。

  • (d) 用(b)中的结果计算.

  • (e) 假设, 求m 与 n。存在一种以上的可能性吗?如果存在,求出所有的 m 与 n。

(a)
(b)
(c) 证: 令 ,则有,否则存在更大的数 整除 m 与 n。
显然 是能被 p 和 q整除的最小公倍数。又有
(d)
(e)

习题5.5

​ “”算法如下:从给定的正整数 n 出发。如果 n 是偶数则将他除以二;如果是奇数则把它替换成.如此反复进行下去。例如,如果由5开始,则得到数列

如果由7开始,则得到

注意到 1 后数列正好连续重复 ​.一般地,下述两种可能性之一将会出现。
(i) 可能最后会重复出现先前的某数a,这种情况下两个 a 之间的数段会无穷次重复,此时称算法在最后一个不重复值处终止,数列中不同项的个数叫做算法长度。例如,对 5 与 7,算法在 1 处终止。5的算法长度是 6, 7的算法长度是 17.
(ii) 可能从不重复相同的数,此时说算法没有终止。

  • (a) 对 n 的下述每一个开始值,求​的算法长度与终止值。
    • (i) ,(ii) ,(iii)
  • (b) 作进一步实验, 是确定算法是否总是终止,如果终止的话, 它在何处终止?
  • (c) 假定算法在 1 出终止, 设 是开始值为 n 的算法长度。例如.证明.(提示: 如果开始值为,算法的运行结果是什么?)
  • (d) 证明 .
  • (e) 类似于(c) 和 (d), 找出其他条件使得 n 的相继值有相同长度。(使用下一道习题积累的数据可能是有帮助的。)

(a)
(b) 猜想:对于的 始终在 1 处终止
(c)

(d)



(d)

习题5.6

​ 编写程序来运行上题叙述的算法。用户输入 n,程序就会给出 算法的长度L(n)与终止值$$T(n). 用你的程序来制作一个表格,给出所有开始值 的算法长度与终止值。

见代码部分。

代码-GCD与LCM

Java
public int gcd(int x, int y){
    while(y != 0){
        int t = x % y;
        x = y;
        y = t;
    }
    return x;
}
public int LCM(int x, int y){
    if(x == 0 || y == 0) return 0;
    return x * y / gcd(x, y);
}

代码-冰雹数列

Java
public class HailSerial {
    int[] len;//算法长度
    int[] end;//终止值
    int n;//上限
    int ring;//临时变量,环值
    int ring_pre;//环尾值
    public void hail(int n){
        this.n = n;
        len = new int[n + 1];
        end = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            ring = -1;
            //貌似只能使用哈希表,假设我们不知道终点是1,且终点可以是任何数字
            dfs(-1, i, new HashMap<>(), 1);
        }
    }
    private Pair<Integer, Integer> dfs(int last, int cur, Map<Integer, Integer> mp, int dep) {
        if(cur <= n && len[cur] > 0) return new Pair<>(len[cur], end[cur]);
        if(mp.containsKey(cur)){//发现环入口
            ring = cur;//设置环值并开始归的操作
            ring_pre = last;//设置环外的终止值
            return new Pair<>(dep - mp.get(cur), -1);
        }
        mp.put(cur, dep);
        Pair<Integer, Integer> s;
        if(cur % 2 == 0){
            s = dfs(cur, cur / 2, mp, dep + 1);
        }else {
            s = dfs(cur,cur * 3 + 1, mp, dep + 1);
        }
        Pair<Integer, Integer> rs;
        if(ring != -1){//还在环内
            if(cur == ring){//找到环入口,开始出环
                rs = new Pair<>(s.getKey(), ring_pre);
                ring = -1;
            }else {//还在环内,终止值是上一个,算法长度为环长
                rs = new Pair<>(s.getKey(), last);
            }
        }else {
            rs = new Pair<>(s.getKey() + 1, s.getValue());
        }
        if(cur <= n){
            len[cur] = rs.getKey();
            end[cur] = rs.getValue();
        }
        return rs;
    }
    @Test
    public void test(){
        hail(100);
        for (int i = 1; i <= 100; i++) {
            System.out.println(i + ":" + len[i] + ":" + end[i]);
        }
    }
}

第六章 线性方程与最大公因数

习题6.1

​ (a) 求方程

的一组整数解。
​ (b)求方程

的一组整数解。

(a) (b)

习题6.2

​ 求下述方程的所有整数解:

  • (a)
  • (b)
  • (c)

(a)
(b)
(c)

习题6.3

​ 本章叙述的求解包含相当多的代数运算与回代。本题描述计算 的另一种方法,它容易在计算机上应用。

  • (a) 证明图6.1中的算法能计算 的最大公因数 以及方程 的一组特解 .

  • (b) 运用你使用的计算机语言,在计算机上运行上述算法。

  • (c) 用你的程序对下述有序对计算以及 的整数解.

    • (i) (ii) (iii)
  • (d) 时你的程序出问题吗?修改程序使得程序能正确处理这种情况。

  • (e) 为了后面的应用,求出是有用的。修改你的程序,使得程序总能得到的解。(提示:如果是解,则也是解。)

(a) ,且有递推公式,当时返回。使用矩阵法观察, 可以发现 具有相同的迭代矩阵。
(b) 见代码部分
(c) (i) (ii) (iii)
(d) 见代码部分
(e) 见代码部分

习题6.4

​ (a) 求方程

的整数解.
​ (b) 满足什么条件时方程

有整数解?当有解时给出求解的一般方法.
​ (c) 使用 (b) 中的方法求方程

的一组整数解.

(a)
(b) 答: 满足 时有整数解

  • (i) 求解
  • (ii) 求解时方程无整数解,.
  • (iii) 联和(1) (2)求得一组特解,
  • (iv) 求得所有整数解

(c)

习题6.5

​ 假设 . 证明对每个整数 ,方程 有整数解 . (提示:先求 的解再乘以 .)求方程的一组解,尽量让比较小.

习题6.6

​ 有时我们仅对方程的非负整数解感兴趣.

  • (a) 解释为什么方程没有整数解 .

  • (b) 制作形如的数值表,给出不可能出现的数值的猜想,然后证明你的猜想是正确的。

  • (c) 对 的下述值,求不能表示成 ​形式的最大整数.

    ​ (i) (ii) (iii)

  • (d) 设.使用 (c) 中的结果猜想出不能表示成形式的最大整数(用 表示)。对的至少两个值检验你的猜测。

  • (e) 证明你在 (d) 中猜出的公式是正确的.

  • (f) 试将上述问题推广到三项和 .例如,不能表示成 的最大整数是什么。

(a) ???懵了,这不是在特定情况下有解么

(b)

猜想时, 不能表示的最大数为
(c) (i) (ii) (iii)
(d) 如(b)中所猜想.
(e) 证:时, 不能表示的最大数为

  1. 假设存在 使得 , 则有

    ​ 又,与矛盾,

  2. 等式两边同时乘以 可得

    即对所有都可以表示成 ​的形式

(f) 但时, 设不能表示的最大数为M,则有

行列式求解GCD

​ 有时候我们会思考,如果身边只有纸和笔,如何快速有效的算出, 现提供一种有效的方法, 行列式法。以为例。(虽然这种方法是我临时想出来的,但我觉得它早已有之)

​ 那如何用行列式求通解系数呢,观察上式行列式计算结果,取第一行和第三行(行列式右边为0的行)。

代码-乘法逆元GCD法

Java
public int[] _gcd(int a, int b) {
    if(a == 0) return new int[]{0, 1, b};
    if(b == 0) return new int[]{1, 0, a};
    int x = 1, g = a, v = 0, w = b;
    while (w > 0) {
        int q = g / w;
        int t = g % w;
        int s = x - q * v;
        x = v;
        g = w;
        v = s;
        w = t;
    }
    x %= v;
    if(x < 0) x += Math.abs(v);
    int y = (g - a * x) / b;
    //特别地,当g = 1时,称 x 是 a 模 b 下的乘法逆元
    return new int[]{x, y, g};
}

其他

  1. 数论概论第一部分
  2. 数论概论第二部分
  3. 数论概论第四部分
  4. 数论概论第五部分
  5. 数论概论第六部分
评论 (1)