如何在编程中求解线性丢番图方程?

时间:2012-04-03 09:24:40

标签: c++ algorithm equation algebra

我读过关于线性丢番图方程,例如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形成一个等式,对于像Y 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),然后取这两个 gcd lcm 来获取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/

请给我一些测试用例,以便我能弄明白我在哪里做错了?

提前致谢。

2 个答案:

答案 0 :(得分:13)

求解线性丢番图方程

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

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

答案 1 :(得分:0)

问题是输入值是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;
}