Codeforces Round #592 (Div. 2) C (exgcd)

题目链接

C. The Football Season


题意:

给定四个数字 n , p , w , d n,p,w,d ,要求求出 x , y x,y ,使得 x + y < = n   & &   w x + d y = p x+y<=n \ \&\&\ w*x+d*y=p 输出 x , y , n x y x,y,n-x-y

思路:

对于第二个式子有解必然要满足 g c d ( w , d ) p gcd(w,d)|p ,然后可以通过 e x g c d exgcd 求出 x , y x,y 的一个解,然后通过模,得到一个变量的最小正解,从而求出另一个变量,判断一下合不合法即可。

代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
	if(b==0)
	{
		x=1;y=0;
		return a;
	}
	ll gcd=exgcd(b,a%b,x,y),t=x;
	x=y;y=t-(a/b)*y;
	return gcd;
}
long long n,p,w,d;
ll x,y,z;
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	cin>>n>>p>>w>>d;
	ll t=exgcd((ll)w,(ll)d,x,y);
	if(p%t!=0){
		puts("-1");return 0;
	}
	if(d>=w){///分类讨论,防止溢出ll
		x=((p/t)%(d/t)*x%(d/t)+(d/t))%(d/t);
		y=(p-w*x)/d;
		if(x>=0&&y>=0&&x+y<=n){
			printf("%lld %lld %lld\n",x,y,n-x-y);
		}else puts("-1");
	}else{
		y=((p/t)%(w/t)*y%(w/t)+(w/t))%(w/t);
		x=(p-d*y)/w;
		if(x>=0&&y>=0&&x+y<=n){
			printf("%lld %lld %lld\n",x,y,n-x-y);
		}else puts("-1");
	}
}

猜你喜欢

转载自blog.csdn.net/qq_40400202/article/details/102652887