【问题标题】:How to solve Linear Diophantine equations in programming?如何在编程中求解线性丢番图方程?
【发布时间】:2012-04-16 22:38:32
【问题描述】:

我读过关于线性丢番图方程,例如 ax+by=c 被称为丢番图方程,并且仅当 gcd(a,b) divides c 时才给出整数解。

这些方程式在编程竞赛中非常重要。当我遇到这个问题时,我正在搜索互联网。我认为它是丢番图方程的变体。

问题:

我有两个人,X 人和 Y 都站在绳子中间。人物 X 可以一次向左或向右跳跃 A 或 B 单位。人物 Y 可以一次向左或向右跳跃 C 或 D 单位。现在,给了我一个数字 K,我必须找到那个数字。在 [-K,K] 范围内的绳子上可能的位置,这样两个人都可以使用各自的电影多次到达该位置。 (A、B、C、D 和 K 有问题)。

我的解决方案:

我认为这个问题可以用丢番图方程在数学上解决。

我可以像A x_1 + B y_1 = C_1 where C_1 belongs to [-K,K] 那样为X 人形成一个等式,对于像C x_2 + D y_2 = C_2 where C_2 belongs to [-K,K] 那样的Y 人也同样。

现在我的搜索空间减少到只找到 C_1 和 C_2 相同的可能值的数量。这将是我对这个问题的回答。

要找到这些值,我只需要找到 gcd(A,B)gcd(C,D),然后取这两个 gcdlcm 得到 LCM(gcd(A,B),gcd(C,D)) 和然后简单地计算范围 [1,K] 中的点数,这些点是这个 lcm 的倍数。

我的最终答案是2*no_of_multiples in [1,K] + 1

我尝试在我的 C++ 代码中使用相同的技术,但它不起作用(错误答案)。

这是我的代码: http://pastebin.com/XURQzymA

我的问题是:谁能告诉我我是否正确使用了丢番图方程?

如果是,谁能告诉我我的逻辑失败的可能情况。

这些是网站上给出的一些带有问题陈述的测试用例。

A B C D K 作为输入以相同的顺序给出,相应的输出在下一行给出:

2 4 3 6 7

3

1 2 4 5 1

3

10 12 3 9 16

5

这是原始问题的链接。我用简单的语言写了原始问题。您可能会觉得这很困难,但如果您愿意,可以检查一下:

http://www.codechef.com/APRIL12/problems/DUMPLING/

请给我一些测试用例,以便我找出我做错了什么?

提前致谢。

【问题讨论】:

  • 寻求帮助肯定是违反比赛规则的吧?能等比赛先结束吗?
  • 我可以期待一些测试用例或至少一些提示吗?
  • 老兄,您的代码编译并运行,并为示例提供了正确答案。究竟是什么问题? PS:您的 gcd 算法不需要按顺序排列参数;你可以省略 18 行代码。
  • @EddieEdwards:是的。我知道我的代码在示例中运行良好,但不知道为什么我在 codechef 上得到错误答案。任何帮助将不胜感激。
  • 是的,好吧:) 无论如何,他自己解决了这个问题。只是漏掉了一个小细节。而且他现在似乎已经消失得无影无踪了,所以男孩我很乐意帮助他:)

标签: c++ algorithm equation algebra


【解决方案1】:

问题在于输入值是 64 位(最多 10^18),因此 LCM 最多可以达到 128 位,因此l 可能会溢出。由于 k 是 64 位的,溢出的 l 表示 k = 0(所以答案是 1)。您需要检查一下这种情况。

例如:

unsigned long long l=g1/g; // cannot overflow
unsigned long long res;
if ((l * g2) / g2 != l)
{
    // overflow case - l*g2 is very large, so k/(l*g2) is 0
    res = 0;
}
else
{
    l *= g2;
    res = k / l;
}

【讨论】:

  • 抱歉回复晚了,但正如你所说,我正在解决这个问题。你指出的事情似乎是正确的,所以我尝试使用 BigInteger 在 Java 中解决问题,但得到了 NZEC :(我仍在努力并期待解决它。
  • 上面的修复用您的原始代码在几行中完成。你只需要检查溢出(乘然后除,如果结果是正确的,你没有没有溢出),如果发生,设置res = 0
【解决方案2】:

求解线性丢番图方程

ax + by = cgcd(a, b) 除以 c

  1. 将 a、b 和 c 除以 gcd(a,b)。
  2. 现在 gcd(a,b) == 1
  3. 使用Extended Euclidean algorithm 求解 aU + bV = 1
  4. 将方程乘以 c。现在你有 a(Uc) + b (Vc) = c
  5. 您找到了解决方案 x = U*cy = V * c

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多