不定方程(二元一次 )求解的个数问题(代码优化尝试)


给定一个二元一次方程: ax+by=c

输入a b c,然后输出所有可能解的个数。

限定条件: a,b,c 均为正整数,x,y为非负整数。


分析:首先,二元一次方程的解经上述条件的限制,必定有有限个解。而对于 ax+by=c 猜测(a,b,c,x,y 均为整数):

(1) 当 a < b时:方程至多有 m=c/a 个解。
(2) 当 b < a时:方程至多有 m=c/b 个解。
可以用此条件来减少些计算量。(代码中未采用)


以下为没有改进过的代码(执行次数多)

#include
#include
#include

using std::cout;
using std::cin;
using std::endl;
using std::endl;

int count;


int main()
{
    int a, b, c;
    cin >> a >> b >> c;
    int x, y;
    count = 0;
    for (x = 0; x <= 1000; x++)     //直接使用两个for循环
    {
        for (y = 0; y <= 1000; y++)
        {
            if ((a*x + b*y) == c) count++;
        }
    }
    cout<":"<< count << endl;


    system("pause");
    return 0;
}

这里用a=1 b=3 c=18为例子
共执行了1001*1001=1002001次循环。(始终执行1002001次)
时间消耗0.004s左右


优化_1:
开头的猜测:
(1) 当 a < b时:方程至多有 m=c/a 个解。
(2) 当 b < a时:方程至多有 m=c/b 个解。
代码:

if(a<=b) temp_1 = c / a;     //替换的核心部分
    else temp_1 = c / b;



    for (x = 0; x <= temp_1; x++)
    {
        for (y = 0; y <= temp_1; y++)
        {
            if ((a*x + b*y) == c) count++;
            sum++;
        }
    }

a=1 b=3 c=18为例子:
此时: 循环次数:361 时间:0.001s


进一步的优化:

在限制条件下,x必然小于等于c/a, y必然小于等于c/b

    temp_1 = c / a;    //替换的核心部分,将范围变小
    temp_2 = c / b;

    for (x = 0; x <= temp_1; x++)
    {
        for (y = 0; y <= temp_2; y++)
        {
            if ((a*x + b*y) == c) count++;
            sum++;
        }
    }

这里也用a=1 b=3 c=18为例子:
这一次:执行了133次循环,时间为1毫秒(0.001s)


由此可见:最后一种改进最大程度上限制了x,y的范围。在保证正确结果的情况下,有效地减小了消耗。

你可能感兴趣的:(C++算法)