Codeforces 1244C - The Football Season (扩展欧几里得)

Description

思路

题目大意就是求满足\(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;
} 
posted @ 2020-04-10 21:54  limil  阅读(137)  评论(0编辑  收藏  举报