三元不定方程求解
题意
给定四个数: a a a, b b b, c c c, p p p,求以下方程的非负整数解个数:
a x + b y + c z = p ax+by+cz=p ax+by+cz=p
思路
这个方程乍一看有点类似于 a x + b y = c ax+by=c ax+by=c这个方程。既然类似,那么就把上面的方程转化为这个形式就好了:
a x + b y = p − c z ax+by=p-cz ax+by=p−cz
这样,利用扩展欧几里得算法,可以快速的求出上面方程的非负整数解个数。
z z z要怎么处理?一种简单粗暴的方法就是枚举 z z z的所有可能解,然后再一一推导上面的步骤就可以了。
代码
一种可行的代码。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
tuple<ll, ll, ll> exgcd(ll a, ll b) {
if (b == 0)
return {a, 1, 0};
auto [d, x, y] = exgcd(b, a % b);
return {d, y, x - a / b * y};
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
cin >> t;
for (int _ = 1; _ <= t; ++ _) {
ll a, b, c, p;
cin >> a >> b >> c >> p;
ll ans = 0;
auto [d, x0, y0] = exgcd(a, b);
for (ll z = 0; p - c * z >= 0; ++ z) {
ll t = p - c * z;
if (t % d != 0)
continue;
t /= d;
ll x = t * x0, y = t * y0;
ans += max<ll>(0, floor(1.0 * x * d / b) - ceil(-1.0 * y * d / a) + 1);
}
cout << "Case " << _ << ": " << ans << '\n';
}
return 0;
}