Codeforces 1244C - The Football Season (扩展欧几里得)
思路
题目大意就是求满足\(xw + yd = p\)的x和y,其中\(0 \leq x,y \leq n\)。
先求出w和d的最小公约数m,如果m不能整除p则无解;否则全部提出m。然后就可以用扩展欧几里得求出x,y的可行值。
由\(y \geq 0\) 可知 \(p-wx \geq 0\),可得\(x \leq \cfrac{p}{w}\)。故将x加到的取不大于\(\cfrac{p}{w}\)就可以保证x,y均大于0。
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 5e5 + 10;
#define endl '\n'
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll exgcd(ll a, ll b, ll &x, ll &y) { // ax + by = gcd(a, b)
if(b == 0) {
y = 0, x = 1;
return a;
}
ll res = exgcd(b, a%b, x, y);
ll tx = x,ty = y;
x = ty;
y = tx - (a / b) * ty;
return res;
}
bool solve(ll a, ll b, ll c, ll &x, ll &y) { // ax + by = c
if(!c) {
x = y = 0;
return true;
}
ll d = gcd(a, b);
if(c % d) return false;
a /= d, b /= d, c /= d;
exgcd(a, b, x, y);
ll ret = c % b;
x = x * ret;
x = x + (c / a - x) / b * b;
y = (c - a * x) / b;
return true;
}
int main(){
ios::sync_with_stdio(false);
ll n, p, a, b;
cin >> n >> p >> a >> b;
ll x, y;
solve(a, b, p, x, y);
if(x >= 0 && y >= 0 && x + y <= n) cout << x << " " << y << " " << n - x - y << endl;
else cout << -1 << endl;
}