当前位置: 首页 > article >正文

C. Line: 用扩展欧几里得算法求解整数解

一、题目背景

在平面上,一条直线可以用以下方程描述:

Ax+By+C=0Ax + By + C = 0

其中,系数 A,B,CA, B, C 和点的坐标 x,yx, y 均为整数。需要找到一个满足上述方程的点,使得其坐标 x,yx, y 都是整数。如果不存在这样的点,则输出 -1。

输入格式

  • 单行包含三个整数 A,B,CA, B, C,满足: −2×109≤A,B,C≤2×109-2 \times 10^9 \leq A, B, C \leq 2 \times 10^9
  • 保证 A2+B2>0A^2 + B^2 > 0,即 AA 和 BB 不会同时为 0。

输出格式

  • 如果存在满足条件的点,则输出其坐标 x,yx, y(整数解)。
  • 如果不存在满足条件的点,则输出 -1。

样例输入与输出

输入
2 5 3
输出
6 -3
输入
1 2 3
输出
-1

二、题目分析

本题的核心问题是如何找到整数解 (x,y)(x, y),使其满足直线方程 Ax+By+C=0Ax + By + C = 0。考虑到 A,B,CA, B, C 的取值范围较大,且输入输出都要求整数,我们需要一个高效的算法来处理。

1. 方程化简

我们可以将方程 Ax+By+C=0Ax + By + C = 0 化简为:

Ax+By=−CAx + By = -C

令 D=−CD = -C,则问题转化为:

Ax+By=DAx + By = D

此时,我们需要通过数学方法找到整数解 x,yx, y。

2. 扩展欧几里得算法

扩展欧几里得算法是求解线性不定方程 Ax+By=gcd(A,B)Ax + By = gcd(A, B) 的经典方法。其核心思想是通过递归的方式,逆向构造出满足方程的整数解 x,yx, y。

2.1 标准欧几里得算法

欧几里得算法通过不断取余数,递归计算 AA 和 BB 的最大公约数(GCD):

gcd(A,B)=gcd(B,A%B)gcd(A, B) = gcd(B, A \% B)

2.2 扩展欧几里得算法

扩展欧几里得算法在计算 GCD 的同时,还会计算出整数系数 x,yx, y,使得:

Ax+By=gcd(A,B)Ax + By = gcd(A, B)

具体实现为:

  1. 当 B=0B = 0 时,令 x=1,y=0x = 1, y = 0,此时 gcd(A,B)=Agcd(A, B) = A;
  2. 否则,递归调用扩展欧几里得算法,计算: gcd(B,A%B)=Bx′+(A%B)y′gcd(B, A \% B) = Bx' + (A \% B)y' 通过公式展开,得到: x=y′,y=x′−(A//B)y′x = y', \quad y = x' - (A // B)y'
2.3 特殊处理

扩展欧几里得算法只能保证解 x,yx, y 满足 Ax+By=gcd(A,B)Ax + By = gcd(A, B)。对于本题而言,如果 D%gcd(A,B)≠0D \% gcd(A, B) \neq 0,则方程无解,直接输出 -1。


三、解题思路

通过扩展欧几里得算法求解本题的具体步骤如下:

1. 判断方程是否有解

通过扩展欧几里得算法,计算 gcd(A,B)gcd(A, B)。如果 D%gcd(A,B)≠0D \% gcd(A, B) \neq 0,则方程无解。

2. 求初始解

如果 D%gcd(A,B)=0D \% gcd(A, B) = 0,则将方程两边同时除以 gcd(A,B)gcd(A, B),化简为:

Agx+Bgy=Dg\frac{A}{g}x + \frac{B}{g}y = \frac{D}{g}

其中 g=gcd(A,B)g = gcd(A, B)。使用扩展欧几里得算法,求得初始解 x0,y0x_0, y_0 满足:

Agx0+Bgy0=1\frac{A}{g}x_0 + \frac{B}{g}y_0 = 1

则解的形式为:

x=x0⋅Dg,y=y0⋅Dgx = x_0 \cdot \frac{D}{g}, \quad y = y_0 \cdot \frac{D}{g}

3. 调整解的符号

由于题目要求输出的整数解是满足方程的点,需对解的符号进行调整以满足约束。


四、Python代码实现

以下是完整的Python代码:

def extended_gcd(a, b):
    """扩展欧几里得算法,返回 gcd(a, b) 及满足 Bézout 等式的系数 x, y"""
    if b == 0:
        return a, 1, 0
    gcd, x1, y1 = extended_gcd(b, a % b)
    x = y1
    y = x1 - (a // b) * y1
    return gcd, x, y


def solve_line_equation(a, b, c):
    """
    求解 Ax + By + C = 0 的整数解
    :param a: 方程中的系数 A
    :param b: 方程中的系数 B
    :param c: 方程中的系数 C
    :return: 一个整数解 (x, y) 或 -1(无解)
    """
    # 转化为 Ax + By = -C
    d = -c
    gcd, x, y = extended_gcd(a, b)
    
    # 判断是否有解
    if d % gcd != 0:
        return -1
    
    # 计算整数解
    x = x * (d // gcd)
    y = y * (d // gcd)
    return x, y


def main():
    # 输入三个整数 A, B, C
    a, b, c = map(int, input("请输入 A, B, C(以空格分隔): ").split())
    
    # 求解方程
    result = solve_line_equation(a, b, c)
    
    # 输出结果
    if result == -1:
        print("-1")
    else:
        print(f"{result[0]} {result[1]}")


if __name__ == "__main__":
    main()

五、代码详解

1. 扩展欧几里得算法

函数 extended_gcd 实现了递归算法,返回三个值:

  • 最大公约数 gcd(a,b)gcd(a, b);
  • 系数 x,yx, y,使得 Ax+By=gcd(a,b)Ax + By = gcd(a, b)。

2. 求解方程

函数 solve_line_equation 调用 extended_gcd,通过判断 D%gcd≠0D \% gcd \neq 0 来确定方程是否有解。如果有解,则根据公式计算出解。

3. 主函数

主函数负责读取输入、调用求解函数,并格式化输出结果。


六、样例测试

样例 1

输入
2 5 3
输出
6 -3

样例 2

输入
1 2 3
输出
-1

七、总结

本题考察了扩展欧几里得算法的应用,是数论中经典的整数方程求解问题。通过分解问题,利用数学推导,我们可以高效地解决大范围整数输入的线性方程,代码复杂度为 O(log⁡(min⁡(A,B)))O(\log(\min(A, B)))。希望本文对大家理解扩展欧几里得算法及其应用有所帮助!

如果觉得有用,请点赞和关注支持!



http://www.kler.cn/a/466279.html

相关文章:

  • OpenGL入门最后一章观察矩阵(照相机)
  • 如何通过USB在电脑上查看手机屏幕
  • ip属地的信息准确吗?ip归属地不准确怎么办
  • 基于Java的超级玛丽游戏的设计与实现【源码+文档+部署讲解】
  • 网络安全的学习与实践经验(附资料合集)
  • SCAU期末笔记 - 数据库系统概念往年试卷解析
  • 京东一面:MySQL 主备延迟有哪些坑?主备切换策略
  • TypyScript从入门到精通
  • 如何根据数据分布特性,选择合适的聚类算法,以优化K-Means算法对非球形分布数据的聚类效果?
  • 3blue1brow线代笔记
  • 使用 HEIC/HEIF 编码器将 HEIC 转换为 JPEG
  • SQLite 进阶:扩展功能与最佳实践
  • 深入解析爬虫中的算法设计:提升效率与准确度
  • Scala_【3】运算符
  • Upload-labs 第四关(学习记录)
  • Pytorch的自动求导模块
  • 【机器学习】交叉验证:数据世界的“多面侦探”
  • Linux实验报告15-添加系统调用
  • deepin环境下Docker实用指南:核心命令详解
  • 开发AI电子宠物 参考资料
  • 【Jboss/Windows】Tomcat 8 + JDK 8 升级为 Jboss eap 7 + JDK8
  • enzymejest TDD与BDD开发实战
  • Kafka为什么快(高性能的原因)
  • STM32配合可编程加密芯片SMEC88ST的防抄板加密方案设计
  • 如何使用 `uiautomator2` 控制 Android 设备并模拟应用操作_VIVO手机
  • 局网设置mongodb服务的方法。