假设我需要解决以下等式,
ax + by = c
a
,b
和c
是已知值和x
,y
是0到10之间的自然数(包含)。
除了微不足道的解决方案之外,
for (x = 0; x <= 10; x++)
for (y = 0; y <= 10; y++)
if (a * x + b * y == c)
printf("%d %d", x, y);
...有没有办法有效地找到这个独立系统的所有解决方案?
答案 0 :(得分:3)
在您的情况下,由于x
和y
仅采用0
和10
之间的值,因此强力算法可能是最佳选择,因为它需要较少的时间来实现。
但是,如果你必须在更大的范围内找到所有整数解(x, y)
对,你真的应该使用正确的数学工具来解决这个问题。
您正在尝试求解线性丢番图方程,众所周知,当且仅当d
和a
的最大公约数b
存在时,积分解存在划分c
。
如果解决方案不存在,那么你就完成了。否则,您应首先应用Extended Euclidean Algorithm找到等式ax + by = d
的paritcular解决方案。
根据Bézout's identity,所有其他整体解决方案的形式如下:
其中k
是任意整数。
但请注意,我们对ax + by = c
的解决方案感兴趣,我们必须将所有(x, y)
对缩放c / d
。
答案 1 :(得分:0)
通过直接检查for
是否为整数,可以避免第二个(c-a*x)/b
循环。
编辑:我的代码不像我希望的那么干净,因为我在评论中指出了一些粗心的疏忽,但它仍然比嵌套的for
循环更快。
int by;
for (x = 0; x <= 10; x++) {
by = c-a*x; // this is b*y
if(b==0) { // check for special case of b==0
if (by==0) {
printf("%d and any value for y", x);
}
} else { // b!=0 case
y = by/b;
if (by%b==0 && 0<=y && y<=10) { // is y an integer between 0 and 10?
printf("%d %d", x, by/b);
}
}
}
答案 2 :(得分:0)
你只能通过x循环,然后计算y。如果y是整数,并且在0和10之间,则(x,y)是解。
在C:
for (int x = 0; x <= 10; ++x) {
double y = (double)(c - ax) / b;
// If y is an integer, and it's between 0 and 10, then (x, y) is a solution
BOOL isInteger = abs(floor(y) - y) < 0.001;
if (isInteger && 0 <= y && y <= 10) {
printf("%d %d", x, y);
}
}