题意:解两个方程。
思路:首先一些简单的情况特判一下就行了。 重点解释一下 为什么搜索d次:因为在这里可以推导一下,y * d = p - w * x,那么,我们现在想得到一个合法的y是不是要让p - w * x是一个d的倍数?那么假如它现在不是d的倍数,我们是不是可以对x不断的减去,那么(p - w * x) % d的值是不是想要让它为0。而每次的变化量实际上就是w,gcd(w, d)一定是小于d的,并且gcd(w, d)乘以0~d中,一定有一个能被d给整除的。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
ll n,p,d,w;
cin>>n>>p>>w>>d;
ll x1=p/w;
if(x1>n)
{
cout<<-1<<endl;
return 0;
}
ll x2=(p-w*x1)%w;
if(x2==0)
{
cout<<x1<<" "<<0<<" "<<n-x1<<endl;
return 0;
}
ll x3=x2/d;
ll x4=(x2-x3*d)%d;
if(x4==0&&x3+x1<=n)
{
cout<<x1<<" "<<x3<<" "<<n-(x1+x3)<<endl;
return 0;
}
// wx+dy=p;
// y=(p-wx)/d;
for(int i=1;i<=d;i++) // 重点解释
{
ll tt1=x1-i;
ll tt2=(p-tt1*w)/d;
if(tt1>=0&&tt2>=0&&n-(tt1+tt2)>=0&&(p-tt1*w)%d==0)
{
cout<<tt1<<" "<<tt2<<" "<<n-(tt1+tt2)<<endl;
return 0;
}
}
cout<<-1<<endl;
return 0;
}
附上 扩欧方法
#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;
}
int g=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return g;
}
int main()
{
ll n,p,w,d;
cin>>n>>p>>w>>d;
ll x1, x2,x3;
x1 = p/w;
if(p%w == 0){
if(x1<=n){
cout<<x1<<' '<<0<<' '<<n-x1;
}
else cout<<-1;
return 0;
}
x2 = p%w/d;
x3 = p%w%d;
if(x3 == 0){
if(x1+x2<=n){
cout<<x1<<' '<<x2<<' '<<n-x1-x2;
}
else cout<<-1;
return 0;
}
ll x,y;
ll dd=exgcd(w,d,x,y);
ll c=d-x3;
if(c%dd)
{
cout<<"-1"<<endl;
return 0;
}
x=x*c/dd;
ll t=d/dd;
if(x>=0){
x=x%t;
}
else{
x=(x%t+t)%t;
}
if(x > x1){
cout<<-1;
return 0;
}
else{
x1 -= x;
x2 += (x3+x*w)/d;
if(x1+x2<=n){
cout<<x1<<' '<<x2<<' '<<n-x1-x2;
}
else cout<<-1;
}
return 0;
}